Spring boot 之内嵌服务器
什么是内嵌式服务器
所谓内嵌式服务器就是不需要我们单独部署,集成到Spring Boot中的服务器。
回想一下,我们如何访问传统的web项目?首先我们需要在系统(如linux系统)中安装web服务器(如tomcat),然后将我们的应用程序打包成war,再将war包放入tomcat目录下的webapps,启动Tomcat,才可以正常访问我们的web项目。
那内嵌式服务器有什么好处呢?好处就是不需要我们进行上述繁琐的操作了,Spring boot会直接将项目打包成jar包,但是这个jar包和我们传统意义的jar不一样,这个jar可以使用 java -jar *.jar命令直接运行,但是不可以被其他项目依赖,而传统的jar可以被其他项目依赖,但是不能够被直接运行,所以虽然两者都被称为jar包,但是两者在目录结构上是有很大不同的。
Spring Boot支持哪些内嵌式服务器
我们以 2.2.6.RELEASE版本的Spring Boot为例,其支持三种内嵌式服务器:tomcat、jetty和undertow。
三者的区别:
- jetty适合交互式消息
- 不支持JSP,并发性能较高
Spring Boot中默认使用tomcat作为内嵌的服务器,但是细心的小伙伴会发现,我们并没有引入tomcat的依赖,那Spring boot是如何知道使用tomcat作为默认的内嵌服务器的呢?其实很简单spring-boot-starter-web中已经包含了spring-boot-starter-tomcat依赖。
改变Spring Boot的内嵌服务器
我们知道Spring Boot使用tomcat作为默认的内嵌服务器,并且有关tomcat 的依赖是在spring-boot-starter-web中默认包含的,所以要改变spring boot的内嵌服务器,首先要剔除默认的tomcat依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<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作为内嵌服务器,方式是一样的,这里不再赘述。
内嵌服务器的常用配置参数
日常开发中,除了会修改内嵌服务器外,有时还会根据需要修改内嵌服务器的配置参数,例如:
//修改请求的端口
server.port=8089
//是否启用压缩
server.compression.enabled=
//针对压缩的类型
server.compression.mime-types=
//响应结果大小超过多大使用压缩
server.compression.min-response-size=
官方提供了很多有关内嵌服务器的配置,如果全都列出来完全没有必要。为了让我们在需要的时候可以方便的找到这些配置参数,我们可以总结一些规律:首先,与内嵌服务器配置相关的参数,一般都是以server开头 ,例如上面的配置;其次,如果我们要配置指定内嵌服务器(如tomcat)的参数,我们可以找server.tomcat开头的参数,同理,如要想要配置jetty的相关参数就找server.jetty开头的参数。
SpringBoot内嵌式服务器的启动原理
详见Spring boot内嵌服务器引擎的实现原理
详见详解SpringBoot内嵌WEB服务器的启动过程
Spring boot中配置SSL
SSL(Secure Sockets Layer 安全套接层)是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密,SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通信提供安全支持。SSL协议分为两层,SSL记录协议建立在TCP之上,为高层协议提供数据封装、压缩、加密等基本功能支持。SSL握手协议建立在SSL记录协议之上,用户实际数据传输开始前进行身份验证、协商加密算法、交换加密秘钥。
HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 [1] 。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。
在了解Spring boot中配置ssl之前,我们先介绍了两个概念:ssl和https,这将有助于我们理解为什么要在springboot中使用ssl配置。
我们知道spring boot项目默认支持http请求,但是http是非安全的,而https是安全的,如果想要spring boot支持https请求,需要怎么做呢?这就需要在spring boot项目中进行ssl有关的配置。
# 是否开启ssl ,true:开启,false:不开启
server.ssl.enabled=true
#证书路径。注意:根绝证书放置位置不同,证书路径的配置也不同,例如:
1.可以写证书的绝对路径
2.如果证书放在项目中resources目录下且和application.properties在同级目录下,写成:classpath:keystore.jks,也就是代码中的写法
3.如果证书和src目录同级,就直接配置:server.ssl.key-store=keystore.jks
server.ssl.key-store: classpath:keystore.jks
#证书密码,此密码与.keystore文件中的一致
server.ssl.key-store-password: 123456
#证书文件类型 注意我们是在Java环境中,常用的证书形式有p12、pkcs12格式、jks格式,如果不是该格式,需要转换;p12、pkcs12是同一个,只是证书的后缀不同而已。
server.ssl.keyStoreType: JKS
# 设定key store的提供者
server.ssl.key-store-provider
#证书别名
server.ssl.keyAlias: tomcat
如果使用了上面的配置就表示springboot应用程序不再在端口8080上支持HTTP连接请求,SpringBoot不支持通过配置application.properties(或yaml)来实现既支持HTTP连接又支持HTTPS连接,如果想要同时支持HTTP和HTTPS,则需要以编程方式配置其中的一个,建议使用application.properties文件来配置HTTPS,以编程方式配置HTTP,这是比较容易的方法。
上面仅仅是springboot中使用https的配置,细心的小伙伴可能会有这样的疑问:keystore.jks是什么?从哪里来的?123456这个密码又是从哪里来的?其实keystore.jks是ssl证书,可以通过不同的方式生成,下面具体讲,而12345就是生成证书中的密码。
获取SSL证书的方式
获取ssl证书的方式大致有两种:利用JDK工具生成证书(测试使用)和从SSL证书授权中心购买证书(生产环境使用)。
利用JDK工具生成证书
每一个JDK或者JRE里都有一个工具叫keytool,它是一个证书管理工具,可以用来生成自签名的证书。具体步骤:
1.首先安装好JDK并配置好环境变量
2.打开cmd控制台,输入:keytool -genkey -alias tomcat,然后回车。如下图:
3.按着图中提示一步步操作
字段解释:
- C字段:Country,单位所在国家,为两位数的国家缩写,如:CN 表示中国;
- ST 字段:State/Province,单位所在州或省;
- L 字段:Locality,单位所在城市/或县区;
- O 字段:Organization,此网站的单位名称;
- OU 字段:Organization Unit,下属部门名称,也常常用于显示其他证书相关信息,如证书类型,证书产品名称或身份验证类型或验证内容等;
- CN 字段:Common Name,网站的域名;
4.找到用户所在盘符目录,这里是C:/users/administrator ,看自己的实际情况,找到生成的证书文件
.keystore 这文件就是证书。
5.然后将证书放置到项目中,具体放置方式上面在介绍server.ssl.key-store参数时已经介绍过,这里不再赘述。到此,就算配置完成了,就可以通过https来请求项目了。
从SSL证书授权中心购买证书
此种方式用于生产的证书获取。阿里云和腾讯云都有这样的服务,具体的这里不再介绍。但是同样可以得到我们想要的证书文件,供我们进行相关的配置。
需要注意的是,日常生产中,微服务一般都是通过网关(gateway)访问的,而网关又是通过nginx访问的,所以很多时候ssl工作直接就在nginx这层完成了,甚至是在F5中完成。
Springboot如何支持同时支持http和https
上面说过,SpringBoot不支持通过配置application.properties(或yaml)来实现既支持HTTP连接又支持HTTPS连接,一种可行的方式是:使用application.properties文件来配置HTTPS,以编程方式配置HTTP,这是比较容易的方法。完成上面的关于https的配置后,下面我们看看如何通过编程的方式实现支持http请求。
代码如下:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication .class, args);
}
// SpringBoot2.x配置HTTPS,并实现HTTP访问自动转向HTTPS
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(){
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
@Bean
public Connector httpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080); // 监听Http的端口
connector.setSecure(false);
connector.setRedirectPort(8443); // 监听Http端口后转向Https端口
return connector;
}
}
这样配置后,我们的项目就即支持http请求又支持https请求了。
嵌入式Reactive Web容器
我们知道,Spring Framework 5.0引入Spring WebFlux,Spring WebFlux是一个新的reactive web应用框架。与Spring MVC不同的是,它不需要the Servlet API,是完全异步和非阻塞的。而我们上面所讲的都属于嵌入式Servlet Web容器,很显然是无法运行一个reactive web应用的,幸运的是Spring boot 2.0开始支持了嵌入式Reactive Web 容器,但这并不是默认的选项。
需要注意的是,当spring-boot-starter-web和spring-boot-starter-webflux同时存在时,spring-boot-starter-webflux实际上是会被默认忽略掉的,真正其作用的是spring-boot-starter-web,所以在使用spring-boot-starter-webflux的时候,我们需要把spring-boot-starter-web注释掉。修改后的pom文件如下:
<dependencies>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-web</artifactId>-->
<!--<exclusions>-->
<!--<!– Exclude the Tomcat dependency –>-->
<!--<exclusion>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
更多推荐
所有评论(0)