SpringCloud

一、什么是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 "${要读取的值}"

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容