当前位置: 首页 > news >正文

java6.2 springCloud

前言

  1. 什么是微服务架构

​ 是一种架构风格,它提倡将单一的应用程序划分成一组小的服务,每个服务运行在其独立的线程中。服务之间相互配合,采用轻量级的通信机制相互沟通。(避免统一的、集中的服务管理机制)

优点:

职责单一、开发简单、耦合度低、易于集成第三方、只有业务逻辑

缺点:

分布式系统复杂、运维难度大、通信成本高、数据一致、性能监控

  1. 微服务要解决的问题

(springCloud解决方案)

  • 客户如何访问:服务网关(Netflix Zuul)
  • 服务如何通信:HTTP/RPC
  • 服务如何治理:注册与发现(Netflix Eureka)
  • 风险如何处理:熔断机制(Netflix Hystrix)

五大组件

  • 服务网关(Netflix Zuul)
  • 负载均衡
    • 客户端—Ribbon
    • 服务端—Feign
  • 注册与发现(Netflix Eureka)
  • 熔断器(Netflix Hystrix)
  • 分布式配置(spring cloud config)
  1. springCloud

    springBoot能够快速独立开发一个单体微服务,而springCloud是关注全局的微服务协调治理框架。为各服务之间提供了:配置管理,服务发现,熔断器,路由,微代理,事件总线,全局锁,决策竞选,分布式会话等等的集成服务。

在这里插入图片描述


一. Eureka

  • Netflix 在设计Eureka 时,遵循的是AP原则
  • Eureka 是 Netflix 的核心模块之一。它是基于 Rest 的服务,用于 == 服务注册与发现 == 。

1.1 Eureka Server

Eureka服务器没有后端存储,但注册表中的服务实例都必须发送心跳以保持其注册更新(因此可以在内存中完成)。客户端还具有eureka注册的内存缓存(因此,他们不必为注册表提供每个服务请求)。

  1. 导入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
  1. 配置
server:
  port: 8010
#Eureka配置
eureka:
  instance:
    hostname: localhost  # Eureka服务器实例名称
  client:
    register-with-eureka: false # 是否向注册中心注册自己
    fetch-registry: false       # 是否获得注册表
    service-url:                # 注册中心地址(既自己的地址)
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    # 开启自我保护机制,默认开启
    enable-self-preservation: true
  1. 还需要在启动类添加注解 @EnableEurekaServer 。同时,服务器具有一个带有UI的主页。

1.2 Eureka Client(服务提供)

  1. 导入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
  1. 客户端需要配置才能找到Eureka服务器
spring:
  application:
    name: springCloud-pro-dept  # 当前服务名(多个相同服务的生产者,服务名必须相同)
# 注册到注册中心
eureka:
  instance:
    # 修改描述(可选)
    instance-id: ${spring.application.name}:${server.port}
    # 配置使用主机名注册服务
    hostname: localhost
    # 将主机名替换为ip地址
    prefer-ip-address: true
  client:
    service-url:
      # 注册中心地址
      defaultZone: http://localhost:8010/eureka/
  1. 还需要在启动类添加注解 @EnableEurekaClient 使应用程序成为Eureka“实例”(即注册自身)

    ------------------- 扩展 --------------------

  2. 获得服务列表清单

    • 在启动类添加注解 @EnableDiscoveryClient 从Eureka服务器发现服务实例。
    • 编码
    @RestController
    public class DiscoveryController {
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/discoveryClient")
        public Object discovery(){
            // 获得微服务列表清单
            List<String> services = discoveryClient.getServices();
            System.out.println("discoveryClient=>services");
            System.out.println(services);
            // 根据id,得到某一个服务
            List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PRO-DEPT");
            for (ServiceInstance instance : instances) {
                System.out.println(
                        "Host: "+instance.getHost()+"\t"+
                        "Port: "+instance.getPort()+"\t"+
                        "Uri: "+instance.getUri()+"\t"+
                        "ServiceId: "+instance.getServiceId()
                );
            }
            return this.discoveryClient;
        }
    }
    

1.3 Eureka集群

Eureka可以通过运行多个实例并要求他们相互注册而变得更有弹性。(host必须不一样)

# 注册中心8010配置
---
server:
  port: 8010
#Eureka配置
eureka:
  instance:
    hostname: peer1.com  # Eureka服务器实例名称
  client:
    service-url:         # 指向备份主机,使用','分隔多个主机
      defaultZone: http://peer2.com:8011/eureka/

# 注册中心8011配置
---
server:
  port: 8011
#Eureka配置
eureka:
  instance:
    hostname: peer2.com  # Eureka服务器实例名称
  client:
    service-url:                
      defaultZone: http://peer1.com:8010/eureka/

更改host配置

C:\Windows\System32\drivers\etc\hosts

127.0.0.1 peer1.com
127.0.0.1 peer2.com

最后,相应的生产者程序也需要讲地址指向多个配置中心地址,使用’,'分隔多个主机地址

【 小结 】

  1. Eureka 的自我保护机制

eureka 各节点平等,当某几个服务挂了,不会影响其他正常节点的工作。eureka 有一种自我保护机制,如果15分钟内超过85%的节点没有正常心跳,就会出现网络故障而保留节点,并不会立刻清理(宁可保留所有的服务,也不盲目注销任何可能健康的服务)。

因此当Eureka部分节点失联时,注册中心仍然能继续工作,不会像zookeeper那样使得整个注册服务瘫痪。

  1. CAP原则

C:强一致性 A:可用性 P:容错性

Eureka: AP原则

zookeeper: CP原则

二. Ribbon

  • ribbon 是基于 Netflix Ribbon 实现的一套 客户端负载均衡的工具
  • 它主要功能是提供客户端的软件负载均衡算法(轮询、随机),将用户的请求平摊的分配到多个服务上,从而达到系统的高可用。
  • 负载均衡分类
    • 集中式:在服务是消费者和生产者之间使用独立的 LB,由这个代理把服务转发给生产者。
    • 进程式:把LB 集成到消费方,消费方中注册中心获知可用地址,然后自己选择生产者。(Ribbon属于进程内LB)

Ribbon+Rest(服务调用)

经过以上 Eurelka 的搭建,已经完成了注册中心到服务生产者的实现。而服务生产者也只需要像以往一样将在controller中配置接口,并将服务暴露出去即可。有了生产者,接下来将是消费者如何去远程调用服务。

  1. 导入依赖
<!-- ribbon依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!-- 为了从注册中心获取服务,还需要调入Eureka依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
  1. 编写配置
server:
  port: 80

#Eureka配置
eureka:
  client:
    register-with-eureka: false # 是否向注册中心注册自己
    fetch-registry: true        # 是否获得注册表(默认true)
    service-url:                # 注册中心地址
      defaultZone: http://peer1.com:8010/eureka/,http://peer2.com:8011/eureka/
  1. 还需要在启动类添加注解 @EnableEurekaClient 使应用程序成为Eureka“实例”。(感觉应该可以不用)
  2. 将 RestTemplate 注入 Bean ,并添加 @LoadBalanced注解
@Configuration
public class ConfigBean {
    @Bean
    @LoadBalanced   //负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  1. 使用 RestTemplate 调用服务
@RestController
public class DeptController {
    @Autowired
    RestTemplate rest;

    //private static final String REST_URL_PRE = "http://localhost:8001";
    //通过服务名来访问,等价于http://localhost:8001
    private static final String REST_URL_PRE = "http://SPRINGCLOUD-PRO-DEPT";

    @RequestMapping("/con/getDepts")
    public List<Dept> getDepts(){
        List forObject = rest.getForObject(REST_URL_PRE + "/dept/all", List.class);
        return forObject;
    }
}

------------------- 扩展 --------------------

  1. 自定义负载均衡算法

自定义一个负载均衡算法规则的配置了,并且该类不能在主应用程序上下文中

package com.ribbonRule;  //不在主应用程序上下文中

import ...;

@Configuration
public class MyRule {

    @Bean
    public IRule diyRule(){
        //调用随机规则
        return new RandomRule();
        //可使用自定义的规则类
        //该类必须继承AbstractLoadBalancerRule抽象类
        //自定义规则类可参考例如RandomRule的任意一个规则类
        //return new MyRobinRule();
    }
}

在启动类中添加注解

@RibbonClient(name = "SPRINGCLOUD-PRO-DEPT",configuration = MyRule.class)

三. Feign

  • springCloud 集成了Ribbon 和 Eureka,可在 使用 Feign 时提供负载均衡 的 http 客户端。
  • 使用接口和注解调用微服务,在使编写java Http客户端变得更容易
  • Feign 以 Ribbon+RestTemplate 为基础进一步封装,我们只需要创建一个接口并使用注解方式配置即可完成服务提供方的接口绑定。
  • Feign 集成了 Ribbon

Feign(服务调用)

  1. 导入依赖,由于集成了Ribbon,所以不用导入Ribbon
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!-- 为了从注册中心获取服务,还需要调入Eureka依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
  1. 配置,与使用Ribbon配置相同
server:
  port: 80

#Eureka配置
eureka:
  client:
    register-with-eureka: false # 是否向注册中心注册自己
    fetch-registry: true        # 是否获得注册表(默认true)
    service-url:                # 注册中心地址
      defaultZone: http://peer1.com:8010/eureka/,http://peer2.com:8011/eureka/
  1. 定义一个服务接口,用于接收客户端数据
@Service
//客户端名称,可以使用url属性(绝对值或只是主机名)指定URL
@FeignClient("SPRINGCLOUD-PRO-DEPT")
public interface DeptClientService {
    //客户端提供数据的接口
    @GetMapping("/dept/all")
    List<Dept> getList();
}
  1. 还需要在启动类添加注解 @EnableFeignClients(basePackages={"com.zheng"})
  2. 在 controller 中导入该接口,调用接口服务即可。

四. Hystrix

  • 名词解析
  • 服务雪崩

    一个服务失败导致某个点开始阻塞,进而导致整条链路的服务都失败的情形,我们称之为服务雪崩。

  • 服务熔断

    当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。

    例如:每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

  • 服务降级

    • 两个场景
      1. 当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
      2. 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!
    • 服务降级有很多种降级方式!如开关降级、限流降级、熔断降级!

4.1 Hystrix(服务提供-熔断)

注:前提是先将Eureka Client搭建、配置完成。

  1. 导入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
  1. 使用注解连接备用方法
@GetMapping("/dept/all")
@HystrixCommand(fallbackMethod = "queryAlls")
public List<Dept> queryAll(){
    int err = 10/0;   //程序出错,调用备用方法
    return null;
}
// 备份方法
public List<Dept> queryAlls(){
    List<Dept> list = new ArrayList<>();
    list.add(new Dept(500,"备份方法hystrix","no db"));
    return list;
}
  1. 还需要在启动类添加注解 @EnableCircuitBreaker 开启断路器

4.2 Hystrix+Feign(服务调用-降级)

  • 当目标服务器由于降级down了,调用服务端应做降级的提示。(正常情况目标服务器down了,调用端服务器应报错)
  • 本身就是Feign的功能 ,必须基于Feign,而不需要导入 Hystrix 依赖
  1. 配置
#开启服务降级
feign:
  hystrix:
    enabled: true
  1. 编码,定义一个服务降级实现类
/**
 * 服务降级实现类
 * 当DeptClientService中某一条服务调用报错时,将应急使用当前服务
 */
@Component
public class DeptClientFallback implements FallbackFactory {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public List<Dept> getList() {
                List<Dept> list = new ArrayList<>();
                list.add(new Dept("服务降级,当前服务不可用!"));
                return list;
            }
        };
    }
}
  1. 在 Feign 调用服务的接口中通过 fallbackFactory 属性定义应急类
@FeignClient(value = "SPRINGCLOUD-PRO-DEPT",fallbackFactory = DeptClientFallback.class)

4.3 Dashboard 流监控

【监控面板】

  1. 导入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
  1. 还需要在启动类添加注解 @EnableHystrixDashboard
  2. 访问/hystrix,并将仪表板指向Hystrix客户端应用程序中的单个实例/hystrix.stream端点

【被监控程序】

  • 只有有注册断路器的请求才能被监控

导入依赖

<!--需要导入hystrix-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.7.3</version>
</dependency>

注入类

@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
    //监控面板加入当前 http://ip地址/actuator/hystrix.stream 即可监控
    registrationBean.addUrlMappings("/actuator/hystrix.stream");
    return registrationBean;
}

图示实心圆

  • 健康程度:绿>黄>橙>红
  • 流量越大,圆越大

在这里插入图片描述

五.Zuul

  • Zuul 是路由网关,包含了对请求的代理、路由过滤两个主要的功能。
  • Zuul 也需要注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取其他微服务的消息
  1. 导入依赖
<!--需要导入eureka-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
  1. 配置
server:
  port: 8055

spring:
  application:
    name: springCloud-zull  # 当前服务名(多个相同服务的生产者,服务名必须相同)

eureka:
  instance:
    instance-id: zuul8055.com
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://peer1.com:8010/eureka/,http://peer2.com:8011/eureka/

zuul:
  routes:
  # http://localhost:8055/mydept/ 将代替该服务集群的主机路径
    mydept: {serviceId: SPRINGCLOUD-PRO-DEPT, path: /mydept/**}
  # 不能使用所有的原来的访问路径
  ignored-services: "*"
  1. 还需要在启动类添加注解@EnableZuulProxy

相关文章:

  • 第6章Linux实操篇-开机、重启和用户登录注销
  • 大学网课答案微信公众号接口使用方法
  • 第5章Linux实操篇-Vi和Vim编辑器
  • java6.1 springboot
  • Linux高性能服务器之I/O复用之实例 ET AND LT(图像理解)(14)
  • 计算机毕业设计django基于python大学生心理健康系统(源码+系统+mysql数据库+Lw文档)
  • java计算机毕业设计个性化推荐的扬州农业文化旅游管理平台源码+数据库+系统+lw文档+mybatis+运行部署
  • C#进阶03——常用泛型数据结构类
  • 第4章Linux实操篇-远程登录到Linux服务器
  • 【FPGA教程案例66】硬件开发板调试6——基于FPGA的UDP网口通信和数据传输
  • 第2章Linux基础篇-VM和Linux的安装
  • [NOI2022] 众数 题解
  • linux文件IO
  • 自已定义一个Java异常——子定义异常,和异常遇到的面试题。
  • 计算机视觉+人工智能面试笔试总结——目标检测/图像处理基础题
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • ES6 ...操作符
  • Flex布局到底解决了什么问题
  • Spring Boot快速入门(一):Hello Spring Boot
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 实现菜单下拉伸展折叠效果demo
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 物联网链路协议
  • 智能网联汽车信息安全
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ![CDATA[ ]] 是什么东东
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #{}和${}的区别是什么 -- java面试
  • #DBA杂记1
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET 命令行参数包含应用程序路径吗?
  • .NET 使用配置文件
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .NET构架之我见
  • /proc/interrupts 和 /proc/stat 查看中断的情况
  • @Data注解的作用
  • @我的前任是个极品 微博分析
  • [CSAWQual 2019]Web_Unagi ---不会编程的崽
  • [linux] GFLOPS和TFLOPS的换算
  • [Linux] 用LNMP网站框架搭建论坛
  • [MICROSAR Adaptive] --- Hello Adaptive World
  • [Oh My C++ Diary]类继承和类组合(内嵌类)初始化的不同
  • [poj2891]Strange Way to Express Integers(扩展中国剩余定理)
  • [python] 之 装饰器
  • [python]tkinker的GUI应用执行耗时长的任务