jetty容器升级版本

使用jetty作为容器,想要更早的关闭不需要的链接,减少没用的TCP链接数量,方便同时处理更多请求。

在创建Connector的时候调用setMaxIdleTime(15 * 1000);将链接的最大空闲时间从默认的30秒换成15秒。

但是服务器开始出现报错

WARN  o.e.j.i.nio:720 - javax.net.ssl.SSLException: illegal change cipher spec msg, conn state = 6, handshake state = 1

WARN  o.e.j.i.nio:720 - java.io.IOException: java.lang.IllegalStateException: Internal error

尝试解决未果。

为了减少idleTime尝试升级jetty。之前使用的jetty8.1.16/8.1.19,

maven官网的org.eclipse.jetty决定更新到最新的稳定版9.4.35.v20201120。

netbean成功下载后发现变了很多,跨越了太多的版本,只能从头来。

eclipse官网上jetty教程

pom:

<dependencies>
        <dependency>  
            <groupId>org.eclipse.jetty</groupId>  
            <artifactId>jetty-server</artifactId>  
            <version>${jetty.version}</version>  
        </dependency>
        <dependency>  
            <groupId>org.eclipse.jetty</groupId>  
            <artifactId>jetty-rewrite</artifactId>  
            <version>${jetty.version}</version>  
        </dependency>
        <dependency>  
            <groupId>org.eclipse.jetty</groupId>  
            <artifactId>jetty-util</artifactId>  
            <version>${jetty.version}</version>  
        </dependency>
        <dependency>  
            <groupId>org.eclipse.jetty</groupId>  
            <artifactId>jetty-servlet</artifactId>  
            <version>${jetty.version}</version>  
        </dependency>
        <dependency>  
            <groupId>org.eclipse.jetty</groupId>  
            <artifactId>jetty-servlets</artifactId>  
            <version>${jetty.version}</version>  
        </dependency>
</dependencies>

<properties>
    <jetty.version>9.4.35.v20201120</jetty.version>
</properties>

Main.java:

import io.swagger.jaxrs.config.BeanConfig;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.glassfish.jersey.servlet.ServletContainer;

public class Main {

    public static void main(String[] args) throws Exception {
        startServer();
    }

    /**
     * 服务器 jetty doc
     * https://www.eclipse.org/jetty/documentation/9.4.35.v20201120/#embedding-jetty
     * jetty api
     * https://www.eclipse.org/jetty/javadoc/9.4.35.v20201120/index.html?overview-summary.html
     *
     * @return http server
     * @throws Exception
     */
    private static Server startServer() throws Exception {
        //Set the maximum number of threads.  
        QueuedThreadPool threadPool = new QueuedThreadPool();
        threadPool.setMaxThreads(5000);
        Server server = new Server(threadPool);

        Connector[] connectors = createConnectors(server);
        server.setConnectors(connectors);

        ContextHandlerCollection contexts = createContextHandlerCollection();
        server.setHandler(contexts);

        server.start();
        server.join();
        return server;
    }

    /**
     * 创建connector,acceptors,selectors都用默认值
     *
     * @param server
     * @return
     */
    private static Connector[] createConnectors(final Server server) {
        boolean http = true;
        int httpPort = 8070;
        boolean https = true;
        int httpsPort = 8071;
        long idleTimeOut = 15 * 1000;
        // Configuration
        HttpConfiguration httpConfig = new HttpConfiguration();
//        httpConfig.setSecureScheme("https");
//        httpConfig.setSecurePort(httpsPort);
//        httpConfig.setOutputBufferSize(32768);
        httpConfig.setRequestHeaderSize(32768);
        httpConfig.setResponseHeaderSize(32768);
//        httpConfig.setSendServerVersion(true);
//        httpConfig.setSendDateHeader(false);
        httpConfig.setIdleTimeout(idleTimeOut);
        // httpConfig.addCustomizer(new ForwardedRequestCustomizer());

        ServerConnector httpConnector = null, httpsConnector = null;
        if (http) {
            httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
            httpConnector.setPort(httpPort);
            httpConnector.setIdleTimeout(idleTimeOut);
        }

        if (https) {
            HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
            httpsConfig.addCustomizer(new SecureRequestCustomizer());
            // SSL
//            SslContextFactory sslContextFactory = new SslContextFactory();
            SslContextFactory sslContextFactory = new SslContextFactory.Server();
            sslContextFactory.setKeyStorePath("123.jks");
            sslContextFactory.setKeyManagerPassword("sslPWD");
            sslContextFactory.setKeyStorePassword("jksPWD");

            httpsConnector = new ServerConnector(server,
                    new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                    new HttpConnectionFactory(httpsConfig));
            httpsConnector.setPort(httpsPort);
            httpsConnector.setIdleTimeout(idleTimeOut);
        }

        if (httpsConnector != null) {
            if (httpConnector != null) {
                return new Connector[]{httpsConnector, httpConnector};
            } else {
                return new Connector[]{httpsConnector};
            }
        } else if (httpConnector != null) {
            return new Connector[]{httpConnector};
        } else {
            return null;
        }
    }

    /**
     * 创建handler
     * 
     * @return
     * @throws Exception
     */
    private static ContextHandlerCollection createContextHandlerCollection() throws Exception {
        String path = "/test";
        ContextHandler apiContextHandler = buildContextHandler(path);
        ContextHandler swaggerContextHandler;

        boolean swaggerEnabled = true;
        if (swaggerEnabled) {
            swaggerContextHandler = buildSwaggerUI(path, "com.test.mavenproject.rest");
            return new ContextHandlerCollection(
                    apiContextHandler, swaggerContextHandler
            );
        }
        return new ContextHandlerCollection(apiContextHandler);
    }

    /**
     * servlet handler : 实现后端功能
     *
     * @param basePath
     * @return
     */
    private static ContextHandler buildContextHandler(String basePath) {
        ServletHolder jerseyServlet = new ServletHolder(ServletContainer.class);
        jerseyServlet.setInitParameter("javax.ws.rs.Application", "com.test.mavenproject.inject.TestJerseyConfig");
        jerseyServlet.setInitOrder(1);

        ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
        contextHandler.setContextPath("/");
        contextHandler.addServlet(jerseyServlet, basePath + "/*");
        return contextHandler;
    }

    /**
     * resource handler : swagger文档
     *
     * @param base_path
     * @param resourcePackage
     * @return
     * @throws Exception
     */
    private static ContextHandler buildSwaggerUI(String base_path, String resourcePackage) throws Exception {
        // This configures Swagger  
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion("1.0.0");
        beanConfig.setResourcePackage(resourcePackage);
        beanConfig.setScan(true);
        beanConfig.setBasePath(base_path);
        beanConfig.setDescription("Entity Browser API to demonstrate Swagger with Jersey2 in an "
                + "embedded Jetty instance, with no web.xml or Spring MVC.");
        beanConfig.setTitle("Entity Browser");

        final ResourceHandler swaggerUIResourceHandler = new ResourceHandler();
        swaggerUIResourceHandler.setResourceBase("swaggerui");
        final ContextHandler swaggerUIContext = new ContextHandler();
        swaggerUIContext.setContextPath("/docs");
        swaggerUIContext.setHandler(swaggerUIResourceHandler);
        return swaggerUIContext;
    }
}



/*参数及意义
参数                                    所属模块        说明
jetty.http.host                         http            HTTP链接器绑定的主机地址,默认本机所有有效IP地址。
jetty.http.port                         http            HTTP链接器监听的端口号,默认为8080。
jetty.http.idleTimeout                  http            HTTP链接的最大空闲时间,单位为毫秒,默认为30000。
jetty.http.soLingerTime             	http            HTTP链接器Socket Linger时间,默认为-1,即禁用。
jetty.http.acceptors                    http            HTTP链接器用于接收请求的线程数量,默认为-1,Jetty基于处理器核数选择一个值,具体规则是低于16核为1,低于24核为2,低于32核为3,32核以上为4。
jetty.http.selectors                    http            Socket selector的数量,默认为-1,Jetty基于处理器核数选择一个值,具体规则是低于4核为1,低于8核为3,8核以上为4。
jetty.http.acceptorQueueSize            http            用于设置ServerSocket绑定时的backlog值,输入连接指示(对连接的请求)的最大队列长度。如果队列满时收到连接指示,则拒绝该连接。
jetty.threadPool.minThreads             server          Jetty线程池最小线程数,默认为10。
jetty.threadPool.maxThreads             server          Jetty线程池最大线程数,默认为200。
jetty.threadPool.idleTimeout            server          Jetty线程池线程空闲超时时间,单位为毫秒,默认为60000。
jetty.httpConfig.secureScheme           server          HTTP安全重定向时,URI的Scheme,默认为https。	
jetty.httpConfig.securePort             server          HTTP安全重定向端口,默认为8443。
jetty.httpConfig.outputBufferSize	server          HTTP响应内容缓冲大小,单位为字节,默认为32768。
jetty.httpConfig.outputAggregationSize	server          可以缓冲的响应内容最大写入长度,单位为字节,默认为8192。
jetty.httpConfig.requestHeaderSize	server          HTTP请求头的最大值,单位为字节,默认为8192。
jetty.httpConfig.responseHeaderSize	server          HTTP响应头的最大值,单位为字节,默认为8192。
jetty.server.stopAtShutdown             server          在控制台按下ctrl+c停止Jetty服务器。
jetty.server.stopTimeout                server          Jetty优雅停止的超时时间,单位为毫秒,默认5000。
jetty.server.dumpAfterStart             server          Jetty启动之后,输出服务器、组件以及Web应用的状态。
jetty.server.dumpBeforeStop             server          Jetty关闭之前,输出服务器、组件以及Web应用的状态。
jetty.ssl.host                          ssl             TLS/SSL链接器绑定的主机地址,默认本机所有有效的IP地址。
jetty.ssl.port                          ssl             TLS/SSL链接器监听的端口,默认为8443。
jetty.ssl.idleTimeout                   ssl             TLS/SSL链接器空闲超时时间,单位为毫秒,默认30000。
jetty.ssl.soLingerTime                  ssl             TLS/SSL链接器Socket Linger时间,默认为-1,即禁用。
jetty.ssl.acceptors                     ssl             TLS/SSL链接器用于接收请求的线程数量。
jetty.ssl.selectors                     ssl             TLS/SSL链接器Socket selector的数量。
jetty.ssl.acceptorQueueSize             ssl             设置TLS/SSL链接器ServerSocket绑定时的backlog值
jetty.ssl.sniHostCheck                  ssl             是否检查请求主机名是否匹配SNI 名称。
jetty.ssl.stsMaxAgeSeconds              ssl             设置Strict-Transport-Security 响应头的过期时间,单位为秒,默认为3153600。
jetty.sslContext.keyStorePath           ssl             密钥库文件路径,相对于$JETTY_BASE。
jetty.sslContext.trustStorePath         ssl             信任库文件路径,相对于$JETTY_BASE。
jetty.sslContext.keyStorePassword	ssl             密钥库密码。	
jetty.sslContext.keyStoreType           ssl             密钥库类型(JCEKS、JKS、DKS、PKCS11、PKCS12)。
jetty.sslContext.keyStoreProvider	ssl             密钥库提供者。
jetty.sslContext.keyManagerPassword	ssl             KeyManager密码。
jetty.sslContext.trustStorePassword	ssl             信任库密码。
jetty.sslContext.trustStoreType         ssl             信任库类型(JCEKS、JKS、DKS、PKCS11、PKCS12)。
jetty.sslContext.trustStoreProvider	ssl             信任库提供者。
jetty.sslContext.needClientAuth         ssl             是否要求客户端证书认证,如果为true并且客户端选择不提供自身的验证信息,则协商将会停止。
jetty.sslContext.wantClientAuth     	ssl             是否请求客户端证书认证,如果为true并且客户端选择不提供其自身的验证信息,则协商将会继续。
jetty.sslContext.sslSessionCacheSize	ssl             SSL会话缓存大小。
jetty.sslContext.sslSessionTimeout	ssl     	SSL会话缓存超时时间,单位为秒。
jetty.gzip.minGzipSize                  ssl             指定一个HTTP响应内容长度的限制,当超过该值时,Jetty启动GZIP压缩。
jetty.gzip.compressionLevel             ssl             GZIP压缩级别。
jetty.gzip.excludedUserAgent            ssl             正则表达式,用于指定禁用GZIP的User Agent。如果请求的User Agent匹配该表达式,则将不启用GZIP压缩。默认为.MSIE.6.0.,即IE6不支持GZIP压缩。
jetty.deploy.monitoredDir               deploy          Jetty部署模块监控目录,相对于$JETTY_BASE,用于热部署监控文件变更。
jetty.deploy.monitoredPath              deploy          Jetty部署模块监控路径(绝对目录),用于热部署监控文件变更。
jetty.deploy.defaultsDescriptorPath	deploy          Web应用使用的默认部署描述文件,该文件中的配置信息将会被所有Web应用继承,默认为/etc/webdefault.xml。
jetty.deploy.scanInterval               deploy          Jetty部署模块扫描监控目录的时间间隔,单位为秒,默认为1秒。
jetty.deploy.extractWars                deploy          是否解压WAR包,默认为true。
jetty.jmxremote.rmihost                 jmx-remote	JMX远程访问绑定的RMI主机地址。
jetty.jmxremote.rmiport                 jmx-remote	JMX远程访问RMI监听的端口,默认为1999。Jetty在启动时,会自动获取参数的键值对,并在加载各个模块时,将参数值以IoC的方式注入到各个组件对象。这是Jetty与Tomcat在参
 */

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值