spring boot2.x已经出来好一阵了,而且spring cloud 的最新Release版本Finchley.RELEASE,默认集成的就是spring boot 2.x,这几天将一个旧项目尝试着从低版本升级到 2.x,踩坑无数,记录一下:
一、gradle的问题
spring boot 2.x 要求gradle版本不能太旧,先把gradle升级到4.6版本,然后编译,各种问题,到gradle官网上查了下,build.gradle有几个小地方要调整
1.1 java-libary 的项目
即:纯工具包这种公用jar,plugins{}必须放在第1行(有buildscript的除外),类似:
1
2
3
plugins {
id
'java-library'
}
然后按官网的教程,compile最好换成implementation
1
2
3
4
5
dependencies {
implementation(
...
)
}
1.2 常规java项目(指带容器能独立运行的项目)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
buildscript {
ext {
springBootVersion =
'2.0.1.RELEASE'
}
repositories {
maven {
url
"http://maven.aliyun.com/nexus/content/groups/public/"
}
...
}
dependencies {
classpath(
`"org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"`)
}
}
apply plugin:
'java'
apply plugin:
'org.springframework.boot'
apply plugin:
'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom
'org.springframework.cloud:spring-cloud-dependencies:Finchley.RELEASE'
}
}<br>...
另外,gradle 高版本编译时,总会有一行讨厌的提示:
Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
编译时,可以加参数:--warning-mode=none 禁止掉,即类似:
gradle build --warning-mode=none -x test
二、依赖jar包版本的问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
dependencies {
...
implementation(
...
'org.springframework.cloud:spring-cloud-starter-consul-discovery'
`,`
'org.springframework.cloud:spring-cloud-starter-consul-config'
`,`
'org.springframework.cloud:spring-cloud-starter-bus-kafka'
`,`
'org.springframework.cloud:spring-cloud-starter-sleuth'
`,`
'org.springframework.cloud:spring-cloud-sleuth-stream:1.3.4.RELEASE'
`,`
'org.springframework.cloud:spring-cloud-starter-hystrix:1.4.4.RELEASE'
`,`
'org.springframework.cloud:spring-cloud-netflix-hystrix-stream'
`,`
'org.springframework.boot:spring-boot-starter-actuator'
`,`
'org.springframework.boot:spring-boot-starter-undertow'
`,`
'org.springframework.boot:spring-boot-starter-mail'
`,`
'org.springframework.boot:spring-boot-starter-jdbc'
`,`
'org.springframework.boot:spring-boot-starter-security'
`,`
'org.slf4j:slf4j-api:1.7.25'
`,`
'ch.qos.logback:logback-core:1.2.3'
`,`
'org.thymeleaf:thymeleaf-spring5:3.0.9.RELEASE'
`,`
'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1'
`,`
'tk.mybatis:mapper-spring-boot-starter:1.2.4'
`,`
'com.github.pagehelper:pagehelper-spring-boot-starter:1.2.3'
)
implementation(
`'com.alibaba:druid:1.1.9'`) {
exclude group:
"com.alibaba"
`, module:
"jconsole"`
exclude group:
"com.alibaba"
`, module:
"tools"`
}
implementation(
`'org.springframework.boot:spring-boot-starter-web'`) {
exclude module:
"spring-boot-starter-tomcat"
exclude module:
"spring-boot-starter-jetty"
}
testCompile
'org.springframework.boot:spring-boot-starter-test'
}
其中
'org.springframework.cloud:spring-cloud-sleuth-stream:1.3.4.RELEASE',
'org.springframework.cloud:spring-cloud-starter-hystrix:1.4.4.RELEASE',
这二项必须指定版本号,否则编译不过。(应该最新的2.x版本的jar包,还没上传到中央仓库,无法自动识别依赖),另外pagehelper这个常用的分页组件,也建议按上面的版本来配置,否则运行时,可能会报错。
三、log4j/log4j2的问题
升级到spring boot 2.x后,不管是配置log4j还是log4j2,运行时总是报堆栈溢出的error,换成logback后,启动正常,建议大家尽量采用默认的logback,依赖项的配置参考上面的。
四、DataSourceBuilder类找不到的问题
spring boot 2.x把这个类换了package,所以找不到了,详情见:
https://stackoverflow.com/questions/50011577/spring-boot-2-0-0-datasourcebuilder-not-found-in-autoconfigure-jar
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/jdbc/DataSourceBuilder.html
解决办法就是引用: org.springframework.boot:spring-boot-starter-jdbc
同时修改代码import新的package: org.springframework.boot.jdbc.DataSourceBuilder
五、安全性的问题
spring boot 2.x加强了安全性,不管访问什么rest url,默认都要求登录,在application.yml里无法通过配置关闭,只能写代码调整:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import
org.springframework.context.annotation.Configuration;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public
class
SecurityConfiguration
extends
WebSecurityConfigurerAdapter {
@Override
protected
void
configure(HttpSecurity http)
throws
Exception {
http.authorizeRequests()
.anyRequest()
.permitAll()
.and()
.csrf()
.disable();
}
}
这样,默认所有url都允许访问(如果是暴露在外网的服务,请慎用)
六、各类actuator监控endpoint的路径变化
spring boot 2.x 里,actuator的endpoint默认路径变成/actuator开头,如果要使用以前的风格,放在/根下,可以在applicatino.yml里参考下面的配置:
1
2
3
4
5
6
7
management:
...
endpoints:
web:
base-path: /
exposure:
include:
"*"
另外/health节点,默认情况下,只能输出很少的信息,详细信息,需要通过配置打开
1
2
3
4
5
6
management:
...
endpoint:
health:
show-details: always
...
七、${spring.cloud.client.ipAddress} 无法识别
spring cloud 2.x里,${spring.cloud.client.ipAddress} 这个写法不识别,一启动就会报错,尝试了多次,无意发现,把A改成小写,居然可以了:
1
2
3
4
spring:
...
application:
name: sr-menu-service:${spring.cloud.client.ipaddress}
感觉这应该是个bug,新版本里估计会修复。
八、MetricWriter、SystemPublicMetrics类找不到的问题
spring boot 2.x里metrics默认换成了micrometer,原来的MetricWriter之类的全干掉了,详情参考官网文档
1
2
3
4
5
6
7
management:
metrics:
export:
statsd:
host:
10.0
`..`
port:
8125
flavor: etsy
上面的配置是启用statsd,然后跑起来就能看到效果,见下图
但是与spring boot 1.x相比,并不会直接输出具体值,要看具体值,可以用 http://localhost:8001/metrics/jvm.memory.used
这其中的VALUE中是jvm占用的内存(包括heap + noheap),如果只想看heap区(即:堆上的内存),可以用
http://localhost:8001/metrics/jvm.memory.used?tag=area:heap
同时在grafana里也能看到效果:
注:目前statsd里的前缀无法修改,代码写死的statsd
如果一台机器上部署多个spring cloud 微服务,grafana里就分不出来了(个人估计以后会改进)。
另外,如果希望通过代码获取这些metrics里具体指标值,可以参考下面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import
io.micrometer.core.instrument.Meter;
import
io.micrometer.core.instrument.MeterRegistry;
import
io.micrometer.core.instrument.Statistic;
import
org.junit.Test;
import
org.springframework.beans.factory.annotation.Autowired;
import
java.util.LinkedHashMap;
import
java.util.Map;
import
java.util.function.BiFunction;
public
class
MetricsTest
extends
BaseTest {
private
String METRIC_MSG_FORMAT =
"Metric >> %s = %d"
`;`
@Autowired
private
MeterRegistry meterRegistry;
@Test
public
void
testStatsdConfig() {
String metric =
"jvm.memory.used"
`;`
Meter meter = meterRegistry.find(metric).meter();
Map<Statistic, Double> stats = getSamples(meter);
logger.info(String.format(METRIC_MSG_FORMAT, metric, stats.get(Statistic.VALUE).longValue()));
}
private
Map<Statistic, Double> getSamples(Meter meter) {
Map<Statistic, Double> samples =
new
LinkedHashMap<>();
mergeMeasurements(samples, meter);
return
samples;
}
private
void
mergeMeasurements(Map<Statistic, Double> samples, Meter meter) {
meter.measure().forEach((measurement) -> samples.merge(measurement.getStatistic(),
measurement.getValue(), mergeFunction(measurement.getStatistic())));
}
private
BiFunction<Double, Double, Double> mergeFunction(Statistic statistic) {
return
Statistic.MAX.equals(statistic) ? Double::max : Double::sum;
}
}
九、swagger里WebMvcConfigurerAdapter过时的问题
WebMvcConfigurerAdapter这个类在最新的spring boot里已经被标识为过时,正常用法参考以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import
org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import
springfox.documentation.builders.ApiInfoBuilder;
import
springfox.documentation.builders.PathSelectors;
import
springfox.documentation.builders.RequestHandlerSelectors;
import
springfox.documentation.service.ApiInfo;
import
springfox.documentation.service.Contact;
import
springfox.documentation.spi.DocumentationType;
import
springfox.documentation.spring.web.plugins.Docket;
import
springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author yangjunming
* @date 13/10/2017
*/
@Configuration
@EnableSwagger2
public
class
SwaggerConfig
extends
WebMvcConfigurationSupport {
@Override
protected
void
addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(
`"swagger-ui.html"`)
.addResourceLocations(
`"classpath:/META-INF/resources/"`);
registry.addResourceHandler(
`"/webjars/**"`)
.addResourceLocations(
`"classpath:/META-INF/resources/webjars/"`);
}
@Bean
public
Docket createRestApi() {
return
new
Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(
`"sr.service.menu.controller"`))
.paths(PathSelectors.any())
.build();
}
private
ApiInfo apiInfo() {
return
new
ApiInfoBuilder()
.title(
`"menu-service online api document"`)
.description(
`"测试服务"`)
.contact(
`new
Contact("菩提树下的杨过"
,
"http://yjmyzz.cnblogs.com/",` `"yjmyzz@126.com"
))`
.version(
`"1.0.0"`)
.build();
}
}
附:一些参考文档:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide
https://spring.io/blog/2017/09/15/security-changes-in-spring-boot-2-0-m4
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Security-2.0
https://github.com/pagehelper/pagehelper-spring-boot
Original url: Access
Created at: 2019-04-19 15:58:30
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论