java|Spring Cloud 随记

主要组件分工
消费者:
Rbbion:负载均衡,响应超时,重试
Hystrix:降级、熔断、依赖隔离、异步任务、请求合并
Fegin:拟RPC接口调用,整合rbbion+hystrix
注册中心:
Eruka:AP分布式注册中心
网关:
Zuul:基于Servlet实现的网关,整合rbbion+hystrix
Getway:
配置中心:
Config:
hystrix-dashboard turbine 多个同名线程池,在dashboard会合成一个显示,Pool Size是所有池总和
java|Spring Cloud 随记
文章图片

当前启动两个微服务,都有@FeignClient(name = "sc-data-service"),设置每个线程池默认大小是10,在dashboard只显示一个sc-data-service,但是Pool Size为两个总和。经测试实际使用中也是各用各的互不干扰。Pool Size初始为0,会随着使用增长,但是不会超过服务设置的max值总和。
依赖隔离ThreadPool命名规则:
Feign:以他的name属性命名,一个FeignClient对应一个pool
【java|Spring Cloud 随记】Hystrix:可以配置ThreadPoolkey,其默认为GroupKey=类名。一个ThreadPoolkey对应一个pool。可以为类/方法单独制定ThreadPoolkey

hystrix启动线程隔离后,ThreadLocal会受影响。
在涉及到hystrix线程尽量避免使用ThreadLocal或将ThreadLocal作为请求传参传递。
使用信号量模式,或是HystrixConcurrencyStrategy解决

Spring Cloud Fegin/RestTemplate组件之间转发http,默认是没有请求头head内容的(cookie也是放在请求头中)
调用方可以添加Fegin拦截器或RestTemplate拦截器,分别实现RequestInterceptor或ClientHttpRequestInterceptor。拦截器在调用方发出http请求时拦截,此时可以为调用请求添加请求头信息再发送到下游服务方。

Spring Cloud Zuul转发http,可将有用信息放在请求头,如用户真实IP
a.zuul转发时注意敏感头设置
zuul转发时注意敏感头设置,application.properties文件中添加 zuul.sensitive-headers=。 sensitiveHeaders的默认值初始值是"Cookie", "Set-Cookie", "Authorization"这三项,可以看到Cookie被列为了敏感信息,所以不会放到新http-head中转发
b.zuul网关添加过滤器,把真实IP放入请求头head中转发:

import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Component; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; @Component public class XForwardedForFilter extends ZuulFilter { private static final String HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR"; @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String remoteAddr = request.getRemoteAddr(); //两种方法都可以 为转发的http请求添加head信息 ctx.getZuulRequestHeaders().put(HTTP_X_FORWARDED_FOR, remoteAddr); ctx.addZuulRequestHeader("USER_HEADER", "USER_HEADER"); return null; }@Override public boolean shouldFilter() { return true; }@Override public String filterType() { return "pre"; }@Override public int filterOrder() { return 0; } }

收到转发的微服务获取ip:
String ip = request.getHeader("HTTP_X_FORWARDED_FOR");


Zuul过滤器之间传递信息
见上边代码,zuul过滤器之间不能通过参数传递信息,但是提供了 RequestContext类通过ThreadLocal来传递信息。
requestContext.set("startTime", System.currentTimeMillis());

zuul个从 接收用户请求+过滤+转发到微服务+接收微服务响应信息+返回给用户,这整个过程中每个请求对应同一个的线程完成。所以ThreadLocal可以完整的串联整个接收转发响应的全部生命周期。

Zuul+SpringSecurty 验证用户登录简单案例
将认证用户的相关信息放入header中, 后端服务可以直接读取使用
@Component public class UserInfoHeaderFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.PRE_TYPE; }@Override public int filterOrder() { return FORM_BODY_WRAPPER_FILTER_ORDER - 1; }@Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); //判断上游Filter传递信息 return (boolean ) ctx.get("login"); }@Override public Object run() { //取出Authentication Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); RequestContext ctx = RequestContext.getCurrentContext(); //验证不为空 且 不是匿名authentication if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) { Object principal = authentication.getPrincipal(); String userInfo; if (principal instanceof SysUser) { SysUser user = (SysUser) principal; userInfo = user.getUsername(); } else { //jwt的token只有name userInfo = authentication.getName(); }//将认证用户的相关信息放入header中, 后端服务可以直接读取使用 ctx.addZuulRequestHeader(SecurityConstants.USER_HEADER, userInfo); ctx.addZuulRequestHeader(SecurityConstants.ROLE_HEADER, CollectionUtil.join(authentication.getAuthorities(), ",")); } else{ //禁止路由 ctx.setSendZuulResponse(false); ] ctx.setResponeseBody("{\"status\":500,\"messgae\":\"需登录!\"}"); //向下游Filter传递信息 ctx.set("login",false); } return null; } }



计算Hystrix线程池数量和响应超时
公式:线程数= 消费者每秒一共发送多少请求数/ 单个线程每秒处理请求数 +缓冲线程数
缓冲线程 为处理不确定因素,比如:网络消耗、某个请求用时过长
响应超时:要依据平均请求处理时间,且Hystrix的超时不小于rbbion的 超时*重试次数总用时。否则不会触发重试,直接服务降级。

服务优雅下线 /actuator/service-registry
management: endpoints: web: exposure: include: service-registry

发送POST请求到/actuator/service-registry 端点。该应用在Eureka Server上的状被标记为DOWN ,但是应用本身其实依然是可以正常对外服务的。

Spring Cloud Config 服务端修改端口
默认端口8888,若想修改端口必须放在bootstrap.yml中,否则无效。bootstrap是boot就先加载的配置文件

转载于:https://www.cnblogs.com/sw008/p/11054315.html

    推荐阅读