Server
> ThreadPool
、Handler
> Connector
启动过程,主要做了以下的事情:
ErrorHandler
没有,则创建一个ThreadPool
、Handler
Connector
// Server.java
@Override
protected void doStart() throws Exception
{
// 1.如果 ErrorHandler 没有,则创建一个
if (_errorHandler == null)
_errorHandler = getBean(ErrorHandler.class);
if (_errorHandler == null)
setErrorHandler(new ErrorHandler());
if (_errorHandler instanceof ErrorHandler.ErrorPageMapper)
LOG.warn("ErrorPageMapper not supported for Server level Error Handling");
_errorHandler.setServer(this);
//2.If the Server should be stopped when the jvm exits, register
//with the shutdown handler thread.
if (getStopAtShutdown())
ShutdownThread.register(this);
//3. Register the Server with the handler thread for receiving
//remote stop commands
ShutdownMonitor.register(this);
//Start a thread waiting to receive "stop" commands.
ShutdownMonitor.getInstance().start(); // initialize
// 4.启动 Server, 将会启动除了 Connector 的其他所有组件
MultiException mex = new MultiException();
try
{
super.doStart();
}
catch (Throwable e)
{
mex.add(e);
}
// 5.最后启动 Connector
if (mex.size() == 0)
{
for (Connector connector : _connectors)
{
try
{
connector.start();
}
catch (Throwable e)
{
mex.add(e);
}
}
}
if (isDumpAfterStart())
dumpStdErr();
mex.ifExceptionThrow();
LOG.info(String.format("Started @%dms", Uptime.getUptime()));
}
比如 embedded-jetty-jsp
server = new Server();
// Define ServerConnector
ServerConnector connector = new ServerConnector(server);
connector.setPort(port);
server.addConnector(connector);
// Create Servlet context
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
servletContextHandler.setResourceBase(baseUri.toASCIIString());
// Since this is a ServletContextHandler we must manually configure JSP support.
enableEmbeddedJspSupport(servletContextHandler);
// Add Application Servlets
servletContextHandler.addServlet(DateServlet.class, "/date/");
// Create Example of mapping jsp to path spec
ServletHolder holderAltMapping = new ServletHolder();
holderAltMapping.setName("foo.jsp");
holderAltMapping.setForcedPath("/test/foo/foo.jsp");
servletContextHandler.addServlet(holderAltMapping, "/test/foo/");
// Default Servlet (always last, always named "default")
ServletHolder holderDefault = new ServletHolder("default", DefaultServlet.class);
holderDefault.setInitParameter("resourceBase", baseUri.toASCIIString());
holderDefault.setInitParameter("dirAllowed", "true");
servletContextHandler.addServlet(holderDefault, "/");
server.setHandler(servletContextHandler);
// Start Server
server.start();
Connector 的实现类 ServerConnector
中,有一个_acceptors的数组,在 Connector 启动的时候, 会根据_acceptors数组的长度创建对应数量的 Acceptor,而 Acceptor 的个数可以配置。
HttpConnectionFactory
, SelectorManager
等Acceptor
, 并启动// AbstractConnector.java
@Override
protected void doStart() throws Exception
{
...
// 启动 HttpConnectionFactory, SelectorManager 等
super.doStart();
...
for (int i = 0; i < _acceptors.length; i++)
{
Acceptor a = new Acceptor(i);
addBean(a);
getExecutor().execute(a);
}
}
Acceptor
本质是一个线程。
// ServerConnector.java
@Override
public void accept(int acceptorID) throws IOException
{
ServerSocketChannel serverChannel = _acceptChannel;
if (serverChannel != null && serverChannel.isOpen())
{
// 阻塞等待客户端的连接
SocketChannel channel = serverChannel.accept();
// 连接成功
accepted(channel);
}
}
// 这里已经连接成功
private void accepted(SocketChannel channel) throws IOException
{
channel.configureBlocking(false);
Socket socket = channel.socket();
configure(socket);
// _manager 是 SelectorManager 实例,里面管理了所有的 Selector 实例
_manager.accept(channel);
}
SelectorManager
启动的时候,会把所有的 ManagedSelector
启动了。
// SelectorManager.java
@Override
protected void doStart() throws Exception
{
_lease = ThreadPoolBudget.leaseFrom(getExecutor(), this, _selectors.length);
for (int i = 0; i < _selectors.length; i++)
{
ManagedSelector selector = newSelector(i);
_selectors[i] = selector;
addBean(selector);
}
super.doStart();
}
ManagedSelector
启动的时候,会启动 SelectorProducer
(使用策略 EatWhatYouKill
)
// ManagedSelector.java
public ManagedSelector(SelectorManager selectorManager, int id)
{
_selectorManager = selectorManager;
_id = id;
SelectorProducer producer = new SelectorProducer();
Executor executor = selectorManager.getExecutor();
_strategy = new EatWhatYouKill(producer, executor);
addBean(_strategy, true);
setStopTimeout(5000);
}
@Override
protected void doStart() throws Exception
{
super.doStart();
_selector = _selectorManager.newSelector();
// The producer used by the strategies will never
// be idle (either produces a task or blocks).
// The normal strategy obtains the produced task, schedules
// a new thread to produce more, runs the task and then exits.
_selectorManager.execute(_strategy::produce);
// Set started only if we really are started
Start start = new Start();
submit(start);
start._started.await();
}
by 斯武丶风晴 https://my.oschina.net/langxSpirit
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有