public static NamesrvController main0 ( String [ ] args) {
try {
NamesrvController controller = createNamesrvController ( args) ;
start ( controller) ;
String tip = "The Name Server boot success. serializeType=" + RemotingCommand . getSerializeTypeConfigInThisServer ( ) ;
log. info ( tip) ;
System . out. printf ( "%s%n" , tip) ;
return controller;
} catch ( Throwable e) {
e. printStackTrace ( ) ;
System . exit ( - 1 ) ;
}
return null ;
}
public static NamesrvController createNamesrvController ( String [ ] args) throws IOException , JoranException {
System . setProperty ( RemotingCommand . REMOTING_VERSION_KEY, Integer . toString ( MQVersion . CURRENT_VERSION) ) ;
Options options = ServerUtil . buildCommandlineOptions ( new Options ( ) ) ;
commandLine = ServerUtil . parseCmdLine ( "mqnamesrv" , args, buildCommandlineOptions ( options) , new PosixParser ( ) ) ;
if ( null == commandLine) {
System . exit ( - 1 ) ;
return null ;
}
final NamesrvConfig namesrvConfig = new NamesrvConfig ( ) ;
final NettyServerConfig nettyServerConfig = new NettyServerConfig ( ) ;
nettyServerConfig. setListenPort ( 9876 ) ;
if ( commandLine. hasOption ( 'c' ) ) {
String file = commandLine. getOptionValue ( 'c' ) ;
if ( file != null ) {
InputStream in = new BufferedInputStream ( new FileInputStream ( file) ) ;
properties = new Properties ( ) ;
properties. load ( in) ;
MixAll . properties2Object ( properties, namesrvConfig) ;
MixAll . properties2Object ( properties, nettyServerConfig) ;
namesrvConfig. setConfigStorePath ( file) ;
System . out. printf ( "load config properties file OK, %s%n" , file) ;
in. close ( ) ;
}
}
if ( commandLine. hasOption ( 'p' ) ) {
InternalLogger console = InternalLoggerFactory . getLogger ( LoggerName . NAMESRV_CONSOLE_NAME) ;
MixAll . printObjectProperties ( console, namesrvConfig) ;
MixAll . printObjectProperties ( console, nettyServerConfig) ;
System . exit ( 0 ) ;
}
MixAll . properties2Object ( ServerUtil . commandLine2Properties ( commandLine) , namesrvConfig) ;
if ( null == namesrvConfig. getRocketmqHome ( ) ) {
System . out. printf ( "Please set the %s variable in your environment to match the location of the RocketMQ installation%n" , MixAll . ROCKETMQ_HOME_ENV) ;
System . exit ( - 2 ) ;
}
LoggerContext lc = ( LoggerContext ) LoggerFactory . getILoggerFactory ( ) ;
JoranConfigurator configurator = new JoranConfigurator ( ) ;
configurator. setContext ( lc) ;
lc. reset ( ) ;
configurator. doConfigure ( namesrvConfig. getRocketmqHome ( ) + "/conf/logback_namesrv.xml" ) ;
log = InternalLoggerFactory . getLogger ( LoggerName . NAMESRV_LOGGER_NAME) ;
MixAll . printObjectProperties ( log, namesrvConfig) ;
MixAll . printObjectProperties ( log, nettyServerConfig) ;
final NamesrvController controller = new NamesrvController ( namesrvConfig, nettyServerConfig) ;
controller. getConfiguration ( ) . registerConfig ( properties) ;
return controller;
}
public static NamesrvController start ( final NamesrvController controller) throws Exception {
if ( null == controller) {
throw new IllegalArgumentException ( "NamesrvController is null" ) ;
}
boolean initResult = controller. initialize ( ) ;
if ( ! initResult) {
controller. shutdown ( ) ;
System . exit ( - 3 ) ;
}
Runtime . getRuntime ( ) . addShutdownHook ( new ShutdownHookThread ( log, new Callable < Void > ( ) {
@Override
public Void call ( ) throws Exception {
controller. shutdown ( ) ;
return null ;
}
} ) ) ;
controller. start ( ) ;
return controller;
}
public boolean initialize ( ) {
this . kvConfigManager. load ( ) ;
this . remotingServer = new NettyRemotingServer ( this . nettyServerConfig, this . brokerHousekeepingService) ;
this . remotingExecutor =
Executors . newFixedThreadPool ( nettyServerConfig. getServerWorkerThreads ( ) , new ThreadFactoryImpl ( "RemotingExecutorThread_" ) ) ;
this . registerProcessor ( ) ;
this . scheduledExecutorService. scheduleAtFixedRate ( new Runnable ( ) {
@Override
public void run ( ) {
NamesrvController . this . routeInfoManager. scanNotActiveBroker ( ) ;
}
} , 5 , 10 , TimeUnit . SECONDS) ;
this . scheduledExecutorService. scheduleAtFixedRate ( new Runnable ( ) {
@Override
public void run ( ) {
NamesrvController . this . kvConfigManager. printAllPeriodically ( ) ;
}
} , 1 , 10 , TimeUnit . MINUTES) ;
if ( TlsSystemConfig . tlsMode != TlsMode . DISABLED) {
try {
fileWatchService = new FileWatchService (
new String [ ] {
TlsSystemConfig . tlsServerCertPath,
TlsSystemConfig . tlsServerKeyPath,
TlsSystemConfig . tlsServerTrustCertPath
} ,
new FileWatchService. Listener ( ) {
boolean certChanged, keyChanged = false ;
@Override
public void onChanged ( String path) {
if ( path. equals ( TlsSystemConfig . tlsServerTrustCertPath) ) {
log. info ( "The trust certificate changed, reload the ssl context" ) ;
reloadServerSslContext ( ) ;
}
if ( path. equals ( TlsSystemConfig . tlsServerCertPath) ) {
certChanged = true ;
}
if ( path. equals ( TlsSystemConfig . tlsServerKeyPath) ) {
keyChanged = true ;
}
if ( certChanged && keyChanged) {
log. info ( "The certificate and private key changed, reload the ssl context" ) ;
certChanged = keyChanged = false ;
reloadServerSslContext ( ) ;
}
}
private void reloadServerSslContext ( ) {
( ( NettyRemotingServer ) remotingServer) . loadSslContext ( ) ;
}
} ) ;
} catch ( Exception e) {
log. warn ( "FileWatchService created error, can't load the certificate dynamically" ) ;
}
}
return true ;
}
public void start ( ) throws Exception {
this . remotingServer. start ( ) ;
if ( this . fileWatchService != null ) {
this . fileWatchService. start ( ) ;
}
}
public void start ( ) {
this . defaultEventExecutorGroup = new DefaultEventExecutorGroup (
nettyServerConfig. getServerWorkerThreads ( ) ,
new ThreadFactory ( ) {
private AtomicInteger threadIndex = new AtomicInteger ( 0 ) ;
@Override
public Thread newThread ( Runnable r) {
return new Thread ( r, "NettyServerCodecThread_" + this . threadIndex. incrementAndGet ( ) ) ;
}
} ) ;
prepareSharableHandlers ( ) ;
ServerBootstrap childHandler =
this . serverBootstrap. group ( this . eventLoopGroupBoss, this . eventLoopGroupSelector)
. channel ( useEpoll ( ) ? EpollServerSocketChannel . class : NioServerSocketChannel . class )
. option ( ChannelOption . SO_BACKLOG, 1024 )
. option ( ChannelOption . SO_REUSEADDR, true )
. option ( ChannelOption . SO_KEEPALIVE, false )
. childOption ( ChannelOption . TCP_NODELAY, true )
. childOption ( ChannelOption . SO_SNDBUF, nettyServerConfig. getServerSocketSndBufSize ( ) )
. childOption ( ChannelOption . SO_RCVBUF, nettyServerConfig. getServerSocketRcvBufSize ( ) )
. localAddress ( new InetSocketAddress ( this . nettyServerConfig. getListenPort ( ) ) )
. childHandler ( new ChannelInitializer < SocketChannel > ( ) {
@Override
public void initChannel ( SocketChannel ch) throws Exception {
ch. pipeline ( )
. addLast ( defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME, handshakeHandler)
. addLast ( defaultEventExecutorGroup,
encoder,
new NettyDecoder ( ) ,
new IdleStateHandler ( 0 , 0 , nettyServerConfig. getServerChannelMaxIdleTimeSeconds ( ) ) ,
connectionManageHandler,
serverHandler
) ;
}
} ) ;
if ( nettyServerConfig. isServerPooledByteBufAllocatorEnable ( ) ) {
childHandler. childOption ( ChannelOption . ALLOCATOR, PooledByteBufAllocator . DEFAULT) ;
}
try {
ChannelFuture sync = this . serverBootstrap. bind ( ) . sync ( ) ;
InetSocketAddress addr = ( InetSocketAddress ) sync. channel ( ) . localAddress ( ) ;
this . port = addr. getPort ( ) ;
} catch ( InterruptedException e1) {
throw new RuntimeException ( "this.serverBootstrap.bind().sync() InterruptedException" , e1) ;
}
if ( this . channelEventListener != null ) {
this . nettyEventExecutor. start ( ) ;
}
this . timer. scheduleAtFixedRate ( new TimerTask ( ) {
@Override
public void run ( ) {
try {
NettyRemotingServer . this . scanResponseTable ( ) ;
} catch ( Throwable e) {
log. error ( "scanResponseTable exception" , e) ;
}
}
} , 1000 * 3 , 1000 ) ;
}
public void run ( ) {
log. info ( this . getServiceName ( ) + " service started" ) ;
while ( ! this . isStopped ( ) ) {
try {
this . waitForRunning ( WATCH_INTERVAL) ;
for ( int i = 0 ; i < watchFiles. size ( ) ; i++ ) {
String newHash;
try {
newHash = hash ( watchFiles. get ( i) ) ;
} catch ( Exception ignored) {
log. warn ( this . getServiceName ( ) + " service has exception when calculate the file hash. " , ignored) ;
continue ;
}
if ( ! newHash. equals ( fileCurrentHash. get ( i) ) ) {
fileCurrentHash. set ( i, newHash) ;
listener. onChanged ( watchFiles. get ( i) ) ;
}
}
} catch ( Exception e) {
log. warn ( this . getServiceName ( ) + " service has exception. " , e) ;
}
}
log. info ( this . getServiceName ( ) + " service end" ) ;
}