1 29 30 package com.caucho.server.cluster; 31 32 import com.caucho.config.BuilderProgram; 33 import com.caucho.config.BuilderProgramContainer; 34 import com.caucho.config.Config; 35 import com.caucho.config.ConfigException; 36 import com.caucho.config.SchemaBean; 37 import com.caucho.config.types.InitProgram; 38 import com.caucho.config.types.Period; 39 import com.caucho.jmx.Jmx; 40 import com.caucho.loader.DynamicClassLoader; 41 import com.caucho.loader.Environment; 42 import com.caucho.loader.EnvironmentBean; 43 import com.caucho.loader.EnvironmentClassLoader; 44 import com.caucho.loader.EnvironmentListener; 45 import com.caucho.loader.EnvironmentLocal; 46 import com.caucho.management.server.ClusterMXBean; 47 import com.caucho.server.port.Port; 48 import com.caucho.server.resin.Resin; 49 import com.caucho.util.L10N; 50 import com.caucho.vfs.Path; 51 import com.caucho.vfs.Vfs; 52 53 import javax.annotation.PostConstruct; 54 import javax.management.ObjectName ; 55 import java.util.ArrayList ; 56 import java.util.logging.Level ; 57 import java.util.logging.Logger ; 58 59 62 public class Cluster 63 implements EnvironmentListener, EnvironmentBean, SchemaBean 64 { 65 private static final L10N L = new L10N(ClusterGroup.class); 66 private static final Logger log = Logger.getLogger(Cluster.class.getName()); 67 68 static protected final EnvironmentLocal<String > _serverIdLocal 69 = new EnvironmentLocal<String >("caucho.server-id"); 70 71 static protected final EnvironmentLocal<Cluster> _clusterLocal 72 = new EnvironmentLocal<Cluster>("caucho.cluster"); 73 74 private String _id = ""; 75 76 private String _serverId = ""; 77 78 private EnvironmentClassLoader _classLoader; 79 80 private Resin _resin; 81 82 private Path _rootDirectory; 83 84 private ClusterAdmin _admin; 85 private ObjectName _objectName; 86 87 private ArrayList <InitProgram> _serverDefaultList 88 = new ArrayList <InitProgram>(); 89 90 private ArrayList <ClusterServer> _serverList 91 = new ArrayList <ClusterServer>(); 92 93 private ClusterServer[] _serverArray = new ClusterServer[0]; 94 95 private ClusterGroup _group; 96 97 private StoreManager _clusterStore; 98 99 private long _clientMaxIdleTime = 30000L; 101 private long _clientFailRecoverTime = 15000L; 102 private long _clientWarmupTime = 60000L; 103 private long _clientBusyTime = 15000L; 104 105 private long _clientReadTimeout = 60000L; 106 private long _clientWriteTimeout = 60000L; 107 private long _clientConnectTimeout = 5000L; 108 109 private BuilderProgramContainer _serverProgram 110 = new BuilderProgramContainer(); 111 112 private Server _server; 113 114 private volatile boolean _isClosed; 115 116 public Cluster(Resin resin) 117 { 118 this(); 119 120 _resin = resin; 121 } 122 123 public Cluster() 124 { 125 _classLoader = new EnvironmentClassLoader(); 126 _classLoader.setId("cluster:??"); 127 128 _clusterLocal.set(this, _classLoader); 129 130 Environment.addEnvironmentListener(this, _classLoader); 131 132 Config.setCurrentVar("cluster", new Var()); 133 134 _rootDirectory = Vfs.getPwd(); 135 } 136 137 140 public static Cluster getLocal() 141 { 142 Cluster cluster = _clusterLocal.get(); 143 144 return cluster; 145 } 146 147 150 public static Cluster getCluster(ClassLoader loader) 151 { 152 Cluster cluster = _clusterLocal.get(loader); 153 154 return cluster; 155 } 156 157 160 public void setId(String id) 161 { 162 if (id == null) 163 throw new NullPointerException (); 164 165 _id = id; 166 167 _classLoader.setId("cluster:" + _id); 168 } 169 170 173 public String getId() 174 { 175 return _id; 176 } 177 178 181 public Resin getResin() 182 { 183 return _resin; 184 } 185 186 189 public ClassLoader getClassLoader() 190 { 191 return _classLoader; 192 } 193 194 197 public String getSchema() 198 { 199 return "com/caucho/server/resin/cluster.rnc"; 200 } 201 202 205 public Path getRootDirectory() 206 { 207 return _rootDirectory; 208 } 209 210 213 public void setRootDirectory(Path rootDirectory) 214 { 215 Vfs.setPwd(rootDirectory); 216 217 _rootDirectory = rootDirectory; 218 } 219 220 223 public ClusterMXBean getAdmin() 224 { 225 return _admin; 226 } 227 228 231 public ClusterServer findServer(String id) 232 { 233 for (int i = _serverList.size() - 1; i >= 0; i--) { 234 ClusterServer server = _serverList.get(i); 235 236 if (server != null && server.getId().equals(id)) 237 return server; 238 } 239 240 return null; 241 } 242 243 246 public void addServerDefault(InitProgram program) 247 throws Throwable 248 { 249 _serverDefaultList.add(program); 250 } 251 252 255 public ClusterServer createServer() 256 throws Throwable 257 { 258 ClusterServer server = new ClusterServer(this); 259 260 server.setIndex(_serverList.size()); 261 262 for (int i = 0; i < _serverDefaultList.size(); i++) 263 _serverDefaultList.get(i).configure(server); 264 265 return server; 266 } 267 268 271 public void addServer(ClusterServer server) 272 throws ConfigException 273 { 274 ClusterServer oldServer = findServer(server.getId()); 275 276 if (oldServer != null) 277 log.warning(L.l("duplicate <server> with id='{0}'", 278 server.getId())); 279 280 _serverList.add(server); 281 _serverArray = new ClusterServer[_serverList.size()]; 282 _serverList.toArray(_serverArray); 283 284 ClusterServer selfServer = getSelfServer(); 285 286 if (selfServer == server) 287 Config.setCurrentVar("server", new ServerVar(server)); 288 } 289 290 293 public ClusterClient findClient(String address, int port) 294 { 295 for (int i = _serverList.size() - 1; i >= 0; i--) { 296 ClusterServer server = _serverList.get(i); 297 ClusterPort clusterPort = server.getClusterPort(); 298 299 if (address.equals(clusterPort.getAddress()) && 300 port == clusterPort.getPort()) { 301 return null; 304 } 305 } 306 307 return null; 308 } 309 310 313 public StoreManager getStore() 314 { 315 return _clusterStore; 316 } 317 318 321 void setStore(StoreManager store) 322 { 323 _clusterStore = store; 324 } 325 326 329 public void setClientMaxIdleTime(Period period) 330 { 331 _clientMaxIdleTime = period.getPeriod(); 332 } 333 334 337 public long getClientMaxIdleTime() 338 { 339 return _clientMaxIdleTime; 340 } 341 342 347 public void setClientLiveTime(Period period) 348 { 349 setClientMaxIdleTime(period); 350 } 351 352 355 public void setClientFailRecoverTime(Period period) 356 { 357 _clientFailRecoverTime = period.getPeriod(); 358 } 359 360 363 public long getClientFailRecoverTime() 364 { 365 return _clientFailRecoverTime; 366 } 367 368 373 public void setClientDeadTime(Period period) 374 { 375 setClientFailRecoverTime(period); 376 } 377 378 381 public void setClientWarmupTime(Period period) 382 { 383 _clientWarmupTime = period.getPeriod(); 384 } 385 386 389 public long getClientWarmupTime() 390 { 391 return _clientWarmupTime; 392 } 393 394 397 public void setClientConnectTimeout(Period period) 398 { 399 _clientConnectTimeout = period.getPeriod(); 400 } 401 402 405 public long getClientConnectTimeout() 406 { 407 return _clientConnectTimeout; 408 } 409 410 413 public void setClientReadTimeout(Period period) 414 { 415 _clientReadTimeout = period.getPeriod(); 416 } 417 418 421 public long getClientReadTimeout() 422 { 423 return _clientReadTimeout; 424 } 425 426 429 public void setClientWriteTimeout(Period period) 430 { 431 } 432 433 public StoreManager createJdbcStore() 434 throws ConfigException 435 { 436 if (getStore() != null) 437 throw new ConfigException(L.l("multiple jdbc stores are not allowed in a cluster.")); 438 439 StoreManager store = null; 440 441 try { 442 Class cl = Class.forName("com.caucho.server.cluster.JdbcStore"); 443 444 store = (StoreManager) cl.newInstance(); 445 446 store.setCluster(this); 447 448 setStore(store); 449 } catch (Throwable e) { 450 log.log(Level.FINER, e.toString(), e); 451 } 452 453 if (store == null) 454 throw new ConfigException(L.l("'jdbc' persistent sessions are available in Resin Professional. See http://www.caucho.com for information and licensing.")); 455 456 return store; 457 } 458 459 public StoreManager createPrivateFileStore() 460 throws ConfigException 461 { 462 StoreManager store = createFileStore(); 463 464 setStore(null); 465 466 return store; 467 } 468 469 public StoreManager createFileStore() 470 throws ConfigException 471 { 472 if (getStore() != null) 473 throw new ConfigException(L.l("multiple file stores are not allowed in a cluster.")); 474 475 StoreManager store = null; 476 477 try { 478 Class cl = Class.forName("com.caucho.server.cluster.FileStore"); 479 480 store = (StoreManager) cl.newInstance(); 481 482 store.setCluster(this); 483 484 setStore(store); 485 } catch (Throwable e) { 486 log.log(Level.FINER, e.toString(), e); 487 } 488 489 if (store == null) 490 throw new ConfigException(L.l("'file' persistent sessions are available in Resin Professional. See http://www.caucho.com for information and licensing.")); 491 492 return store; 493 } 494 495 public StoreManager createClusterStore() 496 throws ConfigException 497 { 498 if (getStore() != null) 499 throw new ConfigException(L.l("multiple cluster stores are not allowed in a cluster.")); 500 501 StoreManager store = null; 502 503 try { 504 Class cl = Class.forName("com.caucho.server.cluster.ClusterStore"); 505 506 store = (StoreManager) cl.newInstance(); 507 508 store.setCluster(this); 509 510 setStore(store); 511 } catch (Throwable e) { 512 log.log(Level.FINER, e.toString(), e); 513 } 514 515 if (store == null) 516 throw new ConfigException(L.l("'cluster' persistent sessions are available in Resin Professional. See http://www.caucho.com for information and licensing.")); 517 518 return store; 519 } 520 521 524 public void addBuilderProgram(BuilderProgram program) 525 { 526 _serverProgram.addProgram(program); 527 } 528 529 532 @PostConstruct 533 public void init() 534 throws ConfigException 535 { 536 String serverId = _serverIdLocal.get(); 537 538 if (serverId == null) 539 serverId = ""; 540 541 ClusterServer self = findServer(serverId); 542 543 if (self != null) 544 _clusterLocal.set(this); 545 else if (_clusterLocal.get() == null && _serverList.size() == 0) { 546 _clusterLocal.set(this); 548 } 549 550 try { 551 String name = _id; 552 553 if (name == null) 554 name = ""; 555 556 ObjectName objectName = Jmx.getObjectName("type=Cluster,name=" + name); 557 558 _admin = new ClusterAdmin(this); 559 560 Jmx.register(_admin, objectName); 561 562 _objectName = objectName; 563 } catch (Throwable e) { 564 log.log(Level.FINER, e.toString(), e); 565 } 566 } 567 568 571 public static String getServerId() 572 { 573 return _serverIdLocal.get(); 574 } 575 576 579 public ObjectName getObjectName() 580 { 581 return _objectName == null ? null : _objectName; 582 } 583 584 587 public ClusterServer getSelfServer() 588 { 589 _serverId = _serverIdLocal.get(); 590 591 return getServer(_serverId); 592 } 593 594 597 public ClusterServer []getServerList() 598 { 599 return _serverArray; 600 } 601 602 605 public ClusterServer getServer(String serverId) 606 { 607 for (int i = 0; i < _serverList.size(); i++) { 608 ClusterServer server = _serverList.get(i); 609 610 if (server != null && server.getId().equals(serverId)) 611 return server; 612 } 613 614 return null; 615 } 616 617 620 public ClusterServer getServer(int index) 621 { 622 for (int i = 0; i < _serverList.size(); i++) { 623 ClusterServer server = _serverList.get(i); 624 625 if (server != null && server.getIndex() == index) 626 return server; 627 } 628 629 return null; 630 } 631 632 635 public ArrayList <ClusterPort> getServerPorts(String serverId) 636 { 637 ArrayList <ClusterPort> ports = new ArrayList <ClusterPort>(); 638 639 for (int i = 0; i < _serverList.size(); i++) { 640 ClusterServer server = _serverList.get(i); 641 642 if (server != null) { 643 ClusterPort port = server.getClusterPort(); 644 645 if (port.getServerId().equals(serverId)) 646 ports.add(port); 647 } 648 } 649 650 return ports; 651 } 652 653 656 Server startServer(ClusterServer clusterServer) 657 throws Throwable 658 { 659 synchronized (this) { 660 if (_server != null) 661 return _server; 662 663 Server server = new Server(clusterServer); 664 665 _serverProgram.configure(server); 666 667 server.start(); 668 669 _server = server; 670 671 return server; 672 } 673 } 674 675 678 public void classLoaderInit(DynamicClassLoader loader) 679 { 680 } 681 682 685 public void classLoaderDestroy(DynamicClassLoader loader) 686 { 687 } 688 689 692 public void environmentStart(EnvironmentClassLoader loader) 693 { 694 try { 695 if (_clusterStore != null) 696 _clusterStore.start(); 697 } catch (Throwable e) { 698 log.log(Level.WARNING, e.toString(), e); 699 } 700 } 701 702 705 public void environmentStop(EnvironmentClassLoader loader) 706 { 707 try { 708 close(); 709 } catch (Throwable e) { 710 log.log(Level.WARNING, e.toString(), e); 711 } 712 } 713 714 717 public void close() 718 { 719 synchronized (this) { 720 if (_isClosed) 721 return; 722 723 _isClosed = true; 724 } 725 726 for (int i = 0; i < _serverList.size(); i++) { 727 ClusterServer server = _serverList.get(i); 728 729 try { 730 if (server != null) 731 server.close(); 732 } catch (Throwable e) { 733 log.log(Level.WARNING, e.toString(), e); 734 } 735 } 736 } 737 738 public String toString() 739 { 740 return "Cluster[" + _id + "]"; 741 } 742 743 746 public class Var { 747 750 public String getId() 751 { 752 return _id; 753 } 754 755 760 public Path getRoot() 761 { 762 return Cluster.this.getRootDirectory(); 763 } 764 765 770 public Path getRootDir() 771 { 772 return getRoot(); 773 } 774 775 780 public Path getRootDirectory() 781 { 782 return getRoot(); 783 } 784 } 785 786 public class ServerVar { 787 private final ClusterServer _server; 788 789 public ServerVar(ClusterServer server) 790 { 791 _server = server; 792 } 793 794 public String getId() 795 { 796 return _server.getId(); 797 } 798 799 private int getPort(Port port) 800 { 801 if (port == null) 802 return 0; 803 804 return port.getPort(); 805 } 806 807 private String getAddress(Port port) 808 { 809 if (port == null) 810 return null; 811 812 String address = port.getAddress(); 813 814 if (address == null || address.length() == 0) 815 address = "INADDR_ANY"; 816 817 return address; 818 } 819 820 private Port getFirstPort(String protocol, boolean isSSL) 821 { 822 if (_server.getPorts() == null) 823 return null; 824 825 for (Port port : _server.getPorts()) { 826 if (protocol.equals(port.getProtocolName()) && (port.isSSL() == isSSL)) 827 return port; 828 } 829 830 return null; 831 } 832 833 public String getAddress() 834 { 835 return getAddress(_server.getClusterPort()); 836 } 837 838 public int getPort() 839 { 840 return getPort(_server.getClusterPort()); 841 } 842 843 public String getHttpAddress() 844 { 845 return getAddress(getFirstPort("http", false)); 846 } 847 848 public int getHttpPort() 849 { 850 return getPort(getFirstPort("http", false)); 851 } 852 853 854 public String getHttpsAddress() 855 { 856 return getAddress(getFirstPort("http", true)); 857 } 858 859 public int getHttpsPort() 860 { 861 return getPort(getFirstPort("http", true)); 862 } 863 864 867 public Path getRoot() 868 { 869 Resin resin = Resin.getLocal(); 870 871 return resin == null ? Vfs.getPwd() : resin.getRootDirectory(); 872 } 873 } 874 } 875 | Popular Tags |