Spring Cloud 随记

主要组件分工

消费者:

Rbbion:负载均衡,响应超时,重试

Hystrix:降级、熔断、依赖隔离、异步任务、请求合并

Fegin:拟RPC接口调用,整合rbbion+hystrix

注册中心:

Eruka:AP分布式注册中心

网关:

Zuul:基于Servlet实现的网关,整合rbbion+hystrix

Getway:

配置中心:

Config:

hystrix-dashboard turbine 多个同名线程池,在dashboard会合成一个显示,Pool Size是所有池总和

当前启动两个微服务,都有@FeignClient(name = "sc-data-service"),设置每个线程池默认大小是10,在dashboard只显示一个sc-data-service,但是Pool Size为两个总和。经测试实际使用中也是各用各的互不干扰。Pool Size初始为0,会随着使用增长,但是不会超过服务设置的max值总和。

依赖隔离ThreadPool命名规则

Feign:以他的name属性命名,一个FeignClient对应一个pool

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

你可能感兴趣的:(java,后端)