zoukankan      html  css  js  c++  java
  • Spring 框架学习 (五)Spring Cloud

    Spring Cloud

    基于自己的理解

    是什么

    一系列组件构成,这些组件用于帮助构建微服务架构的系统。

    解决什么问题

    微服务架构在增加了系统的可维护性,可用性等基础上,增加了系统开发的复杂度:

    • 不同服务之间调用,需要知道每一个服务的地址
      • 对比不使用微服务架构(即使用一整个单独、庞大的系统)时,只要内部调用接口就好了
    • 服务调用时,使用HttpClient/RestTemplate写的代码稍显冗杂
      • 对比单独系统,同样只要内部调用接口就好了
    • 高可用部署时,需要负载均衡访问服务
      • 单独系统同样不存在这个问题
    • 外部调用系统接口时,需要知道系统每一个服务地址
      • 单独系统只有一个地址,所以不存在这个问题
    • 存在服务错误导致的雪崩问题,即如果一个服务挂掉不响应,则相应的上游业务会由于请求卡住,也全部挂掉。
      • 单独系统倒不能说不存在这个问题,但是可能没有这个概念。
    • 微服务数量上升,每个服务都有配置文件,不方便管理。尤其是可能有一些公共配置(比如数据库、redis),重复配置也比较麻烦

    目前初步学习了一些Spring Cloud相关内容,里面的几个组件就是针对这些问题的。

    怎么用

    还是分组件来看

    服务注册发现

    这里包含一个注册服务(一个单独的进程/集群服务),和多个微服务。

    每个微服务客户端向注册服务注册自己的地址,并且也可以从注册服务查询自己需要的微服务的地址。

    在SpringBoot的AutoConfiguration的支持下,注册一般只要添加好相应的依赖,然后配置一下注册服务的地址。客户端就可以自动以应用的名字注册。

    使用时,在应用中通过@EnableDiscoveryClient使能服务查询,通过注入的DiscoveryClient去找到所需要的服务,然后发送请求。服务的查找一般通过服务的名称,或者id。

            List<ServiceInstance> instances = discoveryClient.getInstances("service-name");
            ServiceInstance serviceInstance = instances.get(0);
    		System.out.println(serviceInstance.getUri());//获取服务地址
    

    这样各个客户端/微服务之间不需要写死其他服务的地址,而是通过名字去查询所需要的服务地址。

    不同的注册服务

    其实只试验了一下Eureka和Consul。

    Eureka: 似乎已经停止维护了,可以通过SpringBoot启动一个Eureka服务。

    Consul:是一个单独的二进制文件运行。可以进行健康检查等。

    负载均衡

    通过服务发现,如果一个服务注册了多个实例(高可用部署),那么会发现多个。

    SpringCloud中包含LoadBalancerClient类可以被自动注册,他可以帮助我们自动在多个里选择用于调用的服务。

            ServiceInstance serviceInstance = loadBalancer.choose("service-name");
            System.out.println(serviceInstance.getUri());
    

    Feign

    Feign组件帮助简化调用其他服务代码的书写。

    通过RestTemplate:

    	public void doRequest() {
    	
    		... //获取服务地址等
    		
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> response = null;
            try {
                response = restTemplate.exchange(baseUrl,
                        HttpMethod.GET, getHeaders(), String.class);
            } catch (Exception ex) {
                System.out.println(ex);
            }
            System.out.println(response.getBody());
    		
    		...
    	}
    		
        private static HttpEntity<?> getHeaders() throws IOException {
            HttpHeaders headers = new HttpHeaders();
            headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
            return new HttpEntity<Object>(headers);
        }		
    

    通过Feign:

    	//配置Feign
    	@FeignClient("service-name")
    	public interface RpcService {
    		@RequestMapping(method = RequestMethod.GET, value = "/doRequest")
    		public Object getData();
    
    	}
    	
    	//使用
        @Autowired
        private RpcService rpcService;
    	
        public String doRequest() {
            rpcService.getData();
        }
    

    这里@FeignClient注解会自动查找服务地址,而且还会自动进行负载均衡选择。

    使用Feign时,应用配置类或者Main类需要添加@EnableFeignClients

    服务熔断降级

    熔断,就是当某个服务接口调用多次失败,下一次就不调用了。
    而降级,就是熔断后所做的替代操作。

    比如订单一直失败,这时候在下单,服务端就不去提交订单,而是直接显示,当前系统繁忙,请稍后再试。

    熔断功能可以通过Hystrix实现。

    使用

    应用配置类需要增加@EnableCircuitBreaker注解开启熔断功能。

    在需要熔断的服务上增加:

    @HystrixCommand(fallbackMethod = "getDataFallBack")
    

    这样会使用默认的配置进行熔断,比如10秒超过20次失败就会熔断,调用fallbackMethod处理。

    内部上,使能服务熔断功能,会让服务内部创建一个线程池,用于处理发过来的请求,这样当请求响应不过来,线程池满了的话,也不会消耗其他系统资源。

    微服务网关

    网关作为微服务系统内部和外部之间的桥梁,外部系统不用知道内部微服务各个子服务的地址,也不用去注册发现服务去找地址(因为这对于一个外部应用来说仍显得麻烦),而是将所有请求发给微服务网关,由网关判断微服务的实际地址。

    Zuul

    Zuul似乎是Spring官方推荐的一个微服务网关。

    Zuul本身也向配置中心注册,获取其他服务的中心,但是调用者只要调用Zuul的地址,就可以通过Zuul将请求转发给后端的实际服务。

    Zuul通过配置,来判断入口请求转发给哪个服务。如:

    zuul:
       routes:
          employee:
             path: /emp/**
             service-id: employee-service
          order:
             path: /order/**
             service-id: order-service
    

    这里以emp开头的请求就会分发给employee-service服务,order开头的请求就会发送给order-service

    这里通过service-idZuul会自动实现相同service-id的请求负载均衡。

    配置中心

    将配置放在一个公共服务里进行维护,这个服务就是配置中心。

    Consul

    除了作为注册发现服务,Consul提供了K/V存储功能,可以用于配置中心。

    添加MAVEN依赖:

        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-consul-config</artifactId>
        </dependency>
    

    bootstrap.yml中配置注册中心:

    spring:
       application:
          name: my-service
       profiles:
          active: dev	  
       cloud:
          consul:
             host: localhost
             config:
               enabled: true
               prefix: config
               data-key: data
               profileSeparator: '::'
               format: yaml
               watch:
                  delay: 30  
    

    按照上面的配置,启动时,默认会读取这几个key中的内容作为yaml格式的配置加载(在上方的具有高优先级):

    config/my-service::dev/data
    config/my-service/data
    config/application::dev/data
    config/application/data
    

    这里的key看起来像是目录结构,其实/符号同样是作为key的一部分的。

  • 相关阅读:
    iPhone 6和iPhone 6 plus的AV Foundation框架特性
    实时人脸识别
    相机 视频流数据--预览 拍照 变焦
    AVCaptureStillImageOutput获取静态图像
    jquery返回上一页面
    js闭包
    一些正则匹配
    嵌套 click 第二层 click会叠加 导致 触发 多次
    QPS
    除了汉字全部过滤
  • 原文地址:https://www.cnblogs.com/mosakashaka/p/12609186.html
Copyright © 2011-2022 走看看