一、打包之坑---引入依赖
使用import引入,不再使用parent的方式
<!-- 进行SpringCloud依赖包的导入处理 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud离不开SpringBoot,所以必须要配置此依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
结果就是打包以后并不是SpringBoot的jar,而是一个普通的jar。配置打包插件以后,问题解决
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>cn.net.immortal.user.ImUserStartup</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
二、配置文件之坑
1、 spring cloud当然离不开注册中心,这里使用eureka(听说eureka2.0闭源了,都在换阵地)。
System Status 线上环境肯定不能跟开发,测试一样的配置,当时想改 Environment 然后发现
eureka.instance.environment这个属性,兴高采烈的配置好,启动后发现然并卵啊。
实际上System Status的修改应该是 eureka.environment 然而,看图说话
eureka.environment 是一个警告 eureka.instance.environment是正常的,事实上要修改System Status 的 Environment eureka.environment 才是正确的属性。
2、上下文根
以往习惯于配置上下文根区别应用,然后这一次就倒在了这里
服务注册倒eureka中 服务的status默认是 / 配置了上下文根后,一堆404……
这个不要紧status-page-url-path 或者 status-page-url,home-page-url 通过自己定制还是可以解决的
直到遇到了 hystrixdashboard 和 turbine!!!聚合监控再次然并卵!
上一段turbine的配置
注释掉的地方为,配置了上下文根之后配置,看过turbine这样就是上线文跟不同的应用当做不同的集群来处理,表明hystrixdashboard一个页面一次只能监控一个应用的。多节点组成各个不同的集群这个还是有用的,但是对一般情况来说,我这还聚合个锤子,turbine完全没有发挥应用的作用。
因配置上下文根后发生的问题不少,如果没有特殊需要,不要配置上下文跟,不要配置上下文跟,不要配置上下文跟!
三、服务调用之坑--boot-security
1、配置了boot-security GET请求还好,其他求情无不是401
这个问题还好解决,debug日志看了以后,立刻找到了问题
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/turbine.stream","/actuator/hystrix.stream").antMatchers(HttpMethod.OPTIONS);
}
}
http.csrf().disable(); http.csrf().disable(); http.csrf().disable();禁止csrf即可解决,另外如果 不放过"/turbine.stream","/actuator/hystrix.stream"这两个url, hystrixdashboard 和 turbine 会监控不到。
2、GET请求传参,GET 请求传参方式 1 @PathVariable,2 @RequestParam,
如果这样写就需要吧一个对象的字段打散,而且@PathVariable只适合比较固定的参数,不确定个数个参数对它来说,强人锁男!@RequestParam到时可以解决不确定个数参数的问题,但是使用之后发现,这也过于丑陋了。最后一招,全传String到服务提供方再由提供方进行反序列化,麻烦。除此之外,还有使用过滤器,拦截器等等手段进行处理……难到spring cloud没有意识到这个问题,它真的要开发者,一个方法的参数列表长到丑陋?
一番查找, @SpringQueryMap 应运而生
@GetMapping("/immortal-user/account/list")
ResultVO<PageInfo<ImAccountVO>> select(@SpringQueryMap ImAccountVO imAccountVO);
需要注意是,这个注解需要的spring cloud版本为"Greenwich.RELEASE",我试过,最起码这个版本的上一个版本是没有的。
3、熔断、降级 配置好 hystrix 迫不及待的试了一把,调用结果返回熔断,nice; 然后又试了一把,恩,熔断;了,双试了一把,嗯?熔断了;叒试了一把,卧槽?熔断了,什么鬼?
一番排查
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
hystrix这个属性不配置秒断,脑阔疼。
四、zuul网关之坑--401
通过网关访问服务,GET请求完美,POST: 401.稳住不慌,有前面的经验 crsf().disabled();加上再来一次,还是401,卧槽???
一顿操作,发现服务配置了 security,而 POST请求并没有把Authorization 发送给下游服务……
问题找到了,所以
zuul:
routes:
immortal-user: /immortal-user/**
immortal-article: /immortal-article/**
immortal-garbage: /immortal-garbage/**
host:
socket-timeout-millis: 20000
connect-timeout-millis: 10000
add-proxy-headers: true
sensitive-headers:
- Cookie,Set-Cookie,Authorization
sensitive-headers配上表示 header这几个字段需要传播(前置条件zuulfiter里设置了Authorization)。
五、跨域之坑
基于现在前后端分离的形式,也搞了一把前后端分离,跨域我是配置了,然后不管GET还是POST结果贴脸就给我一个401
排查过程就不说了,直接说原因:
1、zuul配置了security,自然在请求中需要Authorization。
2、配置好后问题并没有解决,查看请求发现是一个OPTIONS请求,对于复杂的http请求,会先来一个OPTIONS求情看看服务是不是活着,以及服务的各种纤细,问题是服务要求Authorization,而OPTIONS是不带有这些东西的……
解决办法:
对于OPTIONS请求直接放过。
3、终于网关跨域成功了。WTF还是401???
下游服务也有security,而OPTIONS问题同上。既然这样
没错解决办法就是在zuulfilter中
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
currentContext.setSendZuulResponse(true);
currentContext.setResponseStatusCode(200);
System.out.println("*****************PostFilter run end*****************");
return null;
}
来一波强制操作。
4、 401 变成了403(好像是403,反正是需要跨域配置)
解决办法:
你想要就给你
HttpServletRequest request = currentContext.getRequest();
response.setHeader("Access-Control-Allow-Origin",corsAddress); //这里注释掉
response.setHeader("Access-Control-Allow-Credentials","true"); //这里注释掉
response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host,Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,Authorization");
response.setHeader("Access-Control-Allow-Methods", "GET, PUT, DELETE, POST, OPTIONS");
response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers");
问题解决。
6、health之坑
因监控什么的
management:
endpoints:
web:
exposure:
include: '*'
include:'*',那么问题来了,暴露/actuator/health什么高位漏洞,只要拿到Authorization访问/actuator/health整个服务就相当于裸奔。
解决办法
配置多个角色,然后
management:
endpoints:
web:
exposure:
include: '*'
exclude: 'shutdown'
endpoint:
shutdown:
enabled: true
health:
roles:
- ADMIN
enabled: true
show-details: when_authorized
roles指定角色可见,并且设置show-details,只有指定角色验证通过时才可见,至于user角色,就是其他服务调用接口时的Authorization。