美文网首页
SpringCloud

SpringCloud

作者: 紫雨杰 | 来源:发表于2018-05-05 16:59 被阅读0次

    一、什么是SpringCloud?

    Spring Cloud是一个基于Spring Boot实现的,为开发者提供了快速构建分布式系统的工具集。
    包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。
    

    二、服务的注册和发现

    1、要想SpringCloud中包含Eureka服务器,需要加入Eureka的依赖。
       Spring Cloud Netflix的Eureka ,eureka是一个服务注册和发现模块。
    
    2、eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳,
       在默认情况下erureka server也是一个eureka client ,如果只作为一个服务注册中心,则必须要在(yml)配置文件
       中指定是一个 server。
    
       通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka server。
    
    3、在SpringBoot的主配置类上添加@EnableEurekaServer注解,启动一个服务注册中心。
    
       eureka server 是有界面的,端口默认为8761
    
    4、服务提供者 (eureka client):服务的被调用方
    
       当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。
       Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除。
    
    5、@EnableDiscoveryClient 与 @EnableEurekaClient 的区别:
    
        ● spring cloud中discovery service有许多种实现(eureka、consul、zookeeper等等),
          @EnableDiscoveryClient基于spring-cloud-commons, @EnableEurekaClient基于spring-cloud-netflix。
    
        ● 其实用更简单的话来说,就是如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,
                             如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。
    
        ●  @EnableEurekaClient注解只能用在服务采用的是eureka作为注册中心,
           如果服务采用的是其它的注册中心,则不能使用,只能使用@EnableDiscoveryClient 。
    

    三、服务消费者(服务调用方)

    在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。
    
    ★ Spring cloud有两种服务调用方式:
                        
               一种是:ribbon + restTemplate;
               另一种是:feign
    
    ★ ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为。Feign默认集成了ribbon。
    
    
    1、服务消费者(restTemplate + ribbon)
    
         ①、在Springboot的主配置类上,添加@EnableDiscoveryClient注解,通过此注解向服务注册中心注册;
    
         ②、并且在主配置类中通过@Bean注解注入一个RestTemplate bean,返回值是注册的bean, 
            方法名是容器中该bean的id;
    
         ③、在注入的RestTemplate bean上添加 @LoadBalanced 注解表明这个RestTemplate 开启了负载均衡的功能;
    
         ④、写一个测试类,使用 @Autowired 注入RestTemplate,然后使用RestTemplate调用服务提供者提供的服务接
            口,可以使用程序名代替具体的Url地址,在Ribben中会根据服务名来选择具体的服务实例,根据服务实例在请求
            的时候会用具体的url替换服务名。
    
    
       通过以上步骤编写完之后,多次调用方法,会发现已经实现了负载均衡,默认是使用的轮询机制。
       此外还有随机访问、响应时间加权等机制实现负载均衡。
    
    
    
    2、服务消费者(Feign)
    
        ● Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。Feign 采用的是基于接口的注解;
        ● Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
    
        ①、导入spring-cloud-starter-feign、spring-cloud-starter-eureka、spring-boot-starter-web依赖;
    
        ②、在配置文件application.yml文件中,指定程序名,端口号,服务注册地址;
    
        ③、在SpringBoot的主配置类上添加@EnableFeignClients注解开启Feign的功能;
    
        ④、定义一个接口,接口上添加@ FeignClient(“服务名”)注解,来指定调用哪个服务;
          在接口中写一个方法,指定调用指定服务的哪个方法;
    
        ⑤、在web层的controller层,写一个controller,用于外界访问
    
      
        启动程序,多次访问,发现也实现负载均衡的效果,不同端口轮询显示
    

    四、断路器(Hystrix)

    断路器.png
      ●  在微服务架构中,根据业务需求把一个复杂的软件应用拆分成一个个的微小服务,服务与服务之间可以相互调用
        【RPC:远程过程调用(Remote Procedure Call)】,在Spring Cloud 中可以使用RestTemplate + Ribbon 或 
         Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%
         可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源
         会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,
         这就是服务故障的“雪崩”效应。
    
      ●  解决这个问题的方法:断路器
    
      ●  Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 
         在微服务架构中,一个请求需要调用多个服务是非常常见的,较底层的服务如果出现故障,会导致连锁故障。
         当对特定的服务的调用,其不可用达到一个阀值(Hystrix 默认是5秒内出现20次), 断路器将会被打开。
         断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。
    
    
    ▲ 在ribbon中使用断路器
    
        ①、首先在pom.xml 添加 spring-cloud-starter-hystrix 依赖;
    
        ②、在SpringBoot的主配置类上添加@EnableHystrix注解开启Hystrix;
    
        ③、在服务消费者调用服务提供者接口的方法上添加@HystrixCommand(fallbackMethod = "方法名")注解,
           该注解对该方法创建了断路器的功能,并指定了fallbackMethod ,fallbackMethod 中的方法返回一个固定值。
    
              @Service
              public class HelloService {
    
                  @Autowired
                  RestTemplate restTemplate;
    
                 @HystrixCommand(fallbackMethod = "hiError")
                  public String hiService(String name) {
                      return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
                  }
    
                  public String hiError(String name) {
                      return "hi,"+name+",sorry,error!";
                  }
              }
    
      如果出现故障,直接返回指定的值,而不是等待响应超时,很好的控制了容器的线程阻塞。
    
    
    ▲ 在Feign中使用断路器
    
        ①、在接口上的@FeignClient注解中添加fallback 属性
    
                @FeignClient(value = "service-hi",fallback = SchedualServiceHiHystric.class)
                public interface SchedualServiceHi {
                    @RequestMapping(value = "/hi",method = RequestMethod.GET)
                    String sayHiFromClientOne(@RequestParam(value = "name") String name);
                }
      
        ②、fallback 属性指定的类实现接口,并注入到Ioc容器中
    
                @Component
                public class SchedualServiceHiHystric implements SchedualServiceHi {
                    @Override
                    public String sayHiFromClientOne(String name) {
                        return "sorry "+name;
                    }
                }
    
       ③、在配置文件中添加:
    
    feign:
      hystrix:
        enabled: true
    
    
    
    ▲ Hystrix Dashboard (断路器:Hystrix 仪表盘)
     
        ①、需要在pom.xml 中添加spring-cloud-starter-hystrix、spring-cloud-starter-hystrix-dashboard、
           spring-boot-starter-actuator依赖;
    
        ②、在SpringBoot的主配置类上添加@EnableHystrix 和 @EnableHystrixDashboard 注解,
           @EnableHystrixDashboard注解是开启hystrixDashboard;
    
        ③、打开浏览器:访问[http://localhost:端口/hystrix,界面如下:
    
    
    HystrixDashboard.png
      ④、点击monitor stream,进入下一个界面,然后新开窗口访问:http://localhost:8764/hi?name=forezp
         然后返回之前的窗口,此时会出现监控界面:
    
    监控界面.png

    五、路由网关(zuul)

      1、在Spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul集群),
         然后再到具体的服。服务统一注册到高可用的服务注册中心Eureka集群,服务的所有的配置文件由配置服务管理,配置服务的配置文件放在git仓库,
         方便开发人员随时改配置。
    
      2、Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。
         zuul默认和Ribbon结合实现了负载均衡的功能。
    
    ▲ 3、zuul的路由转发功能的实现:
         ①、在pom.xml 中导入spring-cloud-starter-zuul依赖;
        
         ②、在SpringBoot的主配置类上添加@EnableZuulProxy,开启zuul的功能;
    
         ③、在配置文件application.yml中加上以下的配置代码:
    
    eureka:
      client:
        serviceUrl:
          #指定服务注册中心的地址
          defaultZone: http://localhost:8761/eureka/
    
    server:
    #指定服务的端口
      port: 8768
    
    #指定服务名
    spring:
      application:
        name: service-zuul
    
    #指定zuul的路由转发功能
    zuul:
      routes:
        #以/to-ribbon/ 开头的请求都转发给service-ribbon服务;
        api-a:
          path: /to-ribbon/**
          serviceId: service-ribbon
    
        #以/to-feign/开头的请求都转发给service-feign服务;
        api-b:
          path: /to-feign/**
          serviceId: service-feign
    
          ④、依次运行工程;打开浏览器访问:http://localhost:8768/to-ribbon/hi?name=tom;浏览器显示:
                  hi tom ,i am from port:8763
    
    
    ▲ 4、zuul的服务过滤功能,可以做一些安全验证,写一个filter  extends ZuulFilter
    
    

    六、分布式配置中心(Spring cloud Config)

    1、在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。
       在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),
       也支持放在远程Git仓库中。
    
       在spring cloud config 组件中,分两个角色,一是config server,二是config client。
    
    
    2、配置服务中心可以从远程程序获取配置信息。【config-server 从git仓库读取配置文件信息】
    
       ①、在pom.xml 中 导入 spring-cloud-config-server依赖;
    
       ②、在SpringBoot的主配置类上添加@EnableConfigServer注解,开启配置服务器的功能;
    
       ③、在配置文件application.properties中进行相关配置:
    
              spring.application.name=服务名
              server.port=端口必须是8888
    
              spring.cloud.config.server.git.uri=配置git仓库地址
              spring.cloud.config.server.git.searchPaths=配置仓库路径
              spring.cloud.config.label=配置仓库的分支
              spring.cloud.config.server.git.username=用户名 (如果Git仓库为公开仓库,可以不填写用户名和密码,如果是私有仓库需要填写)
              spring.cloud.config.server.git.password=密码
            
       ④、 启动程序访问里面的配置文件,http请求地址和资源文件映射如下:
    
                    /{application}/{profile}[/{label}]
                    /{application}-{profile}.yml
                    /{label}/{application}-{profile}.yml
                    /{application}-{profile}.properties
                    /{label}/{application}-{profile}.properties
    
      【注意:】{application}是git仓库中配置文件的文件名,该文件名与config-client的项目中配置文件中的spring.application.name值相同
    
    
    4、本地从配置中心读取值
    
       ①、在pom.xml 中 导入 spring-cloud-starter-config 依赖;
    
       ②、在配置文件application.properties中进行相关配置:
    
              spring.application.name=服务名
              server.port=端口任意
    
              spring.cloud.config.label=指明远程仓库的分支
              spring.cloud.config.profile=激活什么环境
              spring.cloud.config.uri= 指明配置服务中心的网址
    
       ③、写一个controller,可以获取从配置中心读取的值
    
    
    5、config-client可以从config-server 中获取属性,而config-server是从git仓库读取的
    
    
    【注意:】
         ●  config-server 中的配置文件的端口必须是8888
    
         ●  spring.application.name 设置的值必须和git仓库中要读取的配置文件的名字一样
    
            否则config-client 从配置中心读取值时就会报错:Could not resolve placeholder '要读取的值' in value "${要读取的值}"
    
    

    相关文章

      网友评论

          本文标题:SpringCloud

          本文链接:https://www.haomeiwen.com/subject/ctydrftx.html