Servlet web容器对比
jetty的优势:
主要看中其大小和灵活性,如果每一服务器能省1Mb,那么10s内就会省下GB量级的内存;jatty还具有可插拔和可扩的特性,可以最大限度的进行定制
undertow,
使红帽公司开发的一款基于INO的高性能web嵌入式服务器,兼容servlet3.1+规范,最大的特点是“轻量”,加载应用可<10M内存
Tomcat和jetty的比较
- 架构比较
Jetty的架构比Tomcat的更为简单
Jetty的架构是基于Handler来实现的,主要的扩展功能都可以用Handler来实现,扩展简单。Tomcat的架梅是基于容器设计的,进行扩展是需要了解Tomcat的整体设计结构,不易扩展。 - 性能比较
Jetty和Tomcat性能方面差异不大
Jetty可以同时处理大量连接而且可以长时间保持连接,适合于web聊天应用等等。
Jetty的架构简单,因此作为服务器,Jetty可以按需加载组件,减少不需要的组件,减少了服务器内存开销,从而提高服务器性能。
Jetty默认采用NIC结束在处理/O请求上更占优势,在处理静态资源时,性能较高
Tomcat适合处埋少数非常繁忙的链接,也就是说链接生命周期短的话,Tomcat的总休性能更高。Tomcat默认采用B1O处理1/请求,在处理静态资源时,性能较差。 - 其它比较
Jctty的应用更加快速,修改简单,对新的Scrvlct规范的支持较好。
Tomcat目前应用比较广泛,对JavaEE和Servlet的支持更动全面,很多特性会直接集成进来。
一:嵌入式的web容器
嵌入容器的方式
支持三种容器: Tomcat 、Jetty、Undertow
springBoot2.x的重大更新之一,就是支持响应式web server(1.x只支持servlet web容器)
- 更改容器配置
方式一:
在application.yml中设置
如:
server:
port: 8080
#配置访问路径
servlet:
context-path: /show
tomcat:
max-connections: 5000 #设置最大连接数
- 方式二:
创建自定义器,实现WebServerFactoryCustomizer的customize方法,可以设置端口号
package com.zuxia.config;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig {
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> customizer(){
return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
@Override
public void customize(ConfigurableWebServerFactory factory) {
factory.setPort(8809);
}
};
}
}
- 更改使用容器
在pom.xml中 将starter-web中移除spring-boot-starter-tomcat,引入新的容器启动器spring-boot-starter-jetty或spring-boot-starter-undertow
如
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--移除tomcat服务器-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--切换成jetty服务器-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>-->
<!--切换成undertow服务器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
二:响应式的web容器
概念:
- 响应式(Reactive)编程技术针对的就是经典的大数据4V(Volume, Variety, Velocity, Value)中的Velocity,即高并发问题。
- 特点是异步、并发、事件驱动、推送PUSH机制以及观察者模式的衍生。
- 响应式宣言——
We want systems that are Responsive, Resilient, Elastic and Message Driven. We call these Reactive Systems. -The Reactive Manifesto
可响应的、可恢复的、可伸缩的、消息驱动的。 - Mono和Flux是由 Reactor提供的两个Reactor的类型。
- Flux,“流”。它可以触发零个或者多个事件,并根据实际情况结束处理或触发错误。
- Mono,“单子”。最多只触发一个事件,Mono用于在异步任务完成时发出通知。
- Reactive Web容器,默认实现为Netty Web Server.
- Spring Webflux基于Reactor框架实现,在springboct中,nelty web server属于netty和reactor的整合实现。被spring-boot-starterwebflux引入。
嵌入容器的方式
- 引入spring-boot-starter-webflux (与spring-boot-starter-web同时存在时失效),所以使用响应式编程时要注释掉spring-boot-starter-web,如果两者同时存在,则还是使用serlet容器
<!--如果使用响应式编程则要注释掉spring-boot-starter-web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--切换成jetty服务器-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>-->
<!--切换成undertow服务器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
- 编写响应式编程的demo
//响应式的demo
@Bean
public RouterFunction<ServerResponse> hello(){
return route(GET("/hello"),
serverRequest -> ok().body(Mono.just("hello word"),java.lang.String.class));
}
三:查看web应用启动类
方式一:在应用启动后,通过WebServerApplicationContext对象获取类名,在容器启动后回调使用(当前应用为web应用式可用)
public ApplicationRunner runner(WebServerApplicationContext context){
return args -> {
System.out.println("当前web容器的实现类是"+context.getWebServer().getClass());
};
}
方式二: 通过监听WebServerInitializedEvent初始化事件来获取类名,在容器启动前触发
package com.zuxia.config;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class ListenerConfig {
@EventListener(WebServerInitializedEvent.class)
public void onWebServerReady(WebServerInitializedEvent event){
System.out.println("当前web容器的实现类是"+event.getWebServer().getClass().getName());
}
}
四:外置容器方式
- 必须创注一个war项目,需要建立好wcb项目的目录结构,特别是wcbapp/WEB INF/web.xml;
- 嵌入式的Tomcat依赖的scope指定为provided;
<dependency>
<groupld>org.springframework.bcot</groupld>
<artifactld>spring-boot-starter-tomcatc</artifactld>
<scope>provided</scope>
</dependency>
- 必须编写一个SpringBootServletInitializer类的子类,并重写configure方法;
public clss Servletlnitializer extends SpringBootServletInitializer
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
return applcation.sources(SpringBoot04WebJspApplication.class);
}
}
- 部署war包启动