springCloud中提供了restTemplet(httpClient,httpUrlconnection)方式调用其他服务

一、EureKa 注册中心

Eureka:服务注册中心(也可以是一个集群,即Eureka相互注册),对外暴露自己的地址

提供者:定期向eureka注册自己的信息

Eureka服务端

User-service客户端

 

消费者:向Eureka订阅服务,Eureka则会把服务的相关地址列表发送给消费者,并且定期更新

心跳:服务提供者定期向Eureka通过http形式向Eureka刷新自己的状态,30秒发一次

服务下线:

当服务进行正常关闭的时候,服务方会发送一个REST请求给EurekaServer,通知“我已经下线”

服务剔除:

特殊情况下出现内存溢出或者网络波动严重使得服务无法正常工作,而服务注册中心并未收到服务下线的请求,Eureka注册中心在启动的时候会创建一个定时任务,默认每隔一段时间(默认60s),将清单中超时超过90秒的没有续约的服务剔除

自我保护机制:

Eureka自我保护机制,即Eureka会统计服务实例最近15分钟内心跳续约比例是否低于85%,此时如果心跳续约比例高于85%,而某服务仍然不能按时续约,则剔除

二、Zuul 网关

  1. * 什么是zuul,是netflix开源的微服务网关,1.路由,2.控制,3.控流
    * 其核心是一系列的过滤器,可以完成以下功能点:
    * 1.身份认证与安全,识别每一个资源的验证要求,并拒绝那些与要求不符的请求
    * 2.审查,监控,
    * 3.动态路由
    * 5.负载分配,为每一种负载类型分配对应的容量,并弃用超出限定值的请求
    * 6.限流,限制用户流量

  port: 10010
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
zuul:
  prefix: /api
  routes:
    hh:    #路由id
      #path: /user-service/**  #拦截路径
      #url: http://127.0.0.1:8081   #指向路径  指定eureka后,不再匹配url
      #serviceId: user-service  # zuul会默认创建同名serviceId
      user-service: /user/**  #自定义配置
      ignored-services:  #忽略默认配置
        - consumer-service
         #通过路由访问的路径:http://localhost:10010/api/user/user/16
          #不仅实现了路由,且实现负载均衡
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000   #hystrix超时时长
ribbon:
  ConnectionTimeOut: 500   #ribbon超时时长
  ReadTimeOut: 1000

Zuul过滤器,此处以登录过滤为例
@Component
public class LoginFilter extends ZuulFilter {
    @Override//过滤器类型
    public String filterType() {  
        return FilterConstants.PRE_TYPE;   // 此处 = “pre”
    }
    @Override //顺序
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER -1; //此处等于在请求头之前处理
    }


    @Override//要不要过滤
    public boolean shouldFilter() {
        return true;
    }
    /**过滤逻辑
     * run之前会有前置过滤器,之后会有后置后置过滤器
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        //获取请求参数
        RequestContext ctx = RequestContext.getCurrentContext();
        //获取request
        HttpServletRequest request = ctx.getRequest();
    //判断是否存在
        String parameter = request.getParameter("accass-name");
        if(StringUtils.isBlank(parameter)){
            //不存在,未登陆,拦截
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(HttpStatus.SC_FORBIDDEN);
        }

        return null;
    }

三、Ribbon 负载均衡

 

Ribbon默认采用轮训算法,其他算法还有hash、权重、一致性hash

四、Feign 服务调用

@SpringCloudApplication
@EnableFeignClients
public class FeignController {
    //解决服务间远程调用问题
    //Feign  --可以把正常的rest请求,影藏起来,让别人以为这是个本地访问
    //伪装成类似springmvc的注解方式
    //feign还可以为请求和压缩进行压缩,对于大数据量的请求可以开启
    //配置如下:
    /**        feign:
     *          compression:
     *              request:
     *                enabled: true
     *              response:
     *                enabled: true
     *       同时可以对请求的的数据类型,以及压缩大小进行控制
     *feign:
     *  compression:
     *    request:
     *      enabled: true   开启请求
     *      mime-type: text/html.application/xml.application/json   设置压缩数据类型
     *      min-request-size: 2048  大小上线
     */
    @Autowired
    private UserClient userClient;
    @GetMapping("{id}")
    public User getUser(@PathVariable("id") Long id){
        return userClient.queryById(id);
    }
}*
 * //根据服务名字从eureka拉去服务,通过ribbon实现负载均衡,拿到适用的服务
 * 接下来根据getMapping中的url地址去发起请求,得到结果后会自动序列化
 *
 * feign帮我们自动实现了负载均衡,熔断(需要配置,开启熔断)
 */
//@FeignClient("user-service")
@FeignClient(value = "user-service",fallback = UserClientImpl.class) //feign开启熔断设置
public interface UserClient {
    @GetMapping("user/{id}")
    User queryById(@PathVariable("id") Long id);
}

public class UserClientImpl implements UserClient {
    @Override
    public User queryById(Long id) {
        User user = new User();
        user.setUsername("未查询到");
        return user;
    }
}五、Hystix 熔断器

用于处理雪崩问题,假设一个请求需要abcd四个服务执行,如果其中a服务挂掉,则返回结果阻塞,同时如果越来越多的请求进入,则最后http容器的连接数耗尽,此时其他正常的服务也无法使用

解决问题方式:

  1. 线程隔离,服务降级

给每个服务分配一定的线程池,如给a服务5个线程。此时用户来访问a服务,a已经挂了,则最多只能占用5个线程,不会影响到其他服务的线程,同时设定一个超时时长,即请求到a服务之后,无法通过,等待一定时间后,则服务返回一个“服务器繁忙”,同时断开连接,直到能成功为止

E2:比如淘宝双11时候,可以将淘宝直播占用的线程降低,将更多的线程去维护主线程。

在服务启动器上加入注解@EnableCircuitBreaker或者@SpringCloudApplication

@GetMapping("{id}")

@HystrixCommand(fallbackMethod = "queryIdFallback")
public String getUser(@PathVariable("id") Long id)
public String queryIdFallback(Long id){
    return "sorry,服务器正忙";
}

服务降级:语法规定,两个方法的返回值必须一致,方法名与fallbackMethod中指定的方法

也可以全局配置:

同时具体的方法也可以注解指定:

无参方法

服务熔断

 

2、熔断,在最近的20次请求,如果其中有超过一半次都失败,则熔断被访问的服务,同时请求直接返回失败,同时打开熔断器,休眠时间窗(默认5秒)10秒之后会再次尝试,进入半开状态,放一半的请求进入测试,如果仍然失败,则再次进入熔断再次进入半开状态,如果请求测试成功,则关闭熔断器

@HystrixCommand(
        commandProperties =
        {@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "10"), //统计10次
                @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "100000"), //休眠窗口期
                @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "60")//失败百分比
        })

 

 

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐