• 【服务注册框架1】Eureka&nacos 两者的区别


    Eureka

    1.背景:order-service 需要调用 user-service服务 如何知道user-service地址,这时候就需要使用Eureka注册服务,将user-service信息注册到eureka-server,order-service再从eureka-server上拉取。

    2.Eureka-server配置:

    pom.xml(Eureka-server)

        <dependencies>
            <dependency>
                
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    application.yml(Eureka-server)

    server:
      port: 10086
    spring:
      application:
        name: eureka-server
    eureka:
      client:
        service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要写其它Server的地址。
          defaultZone: http://127.0.0.1:10086/eureka  #  defaultZone: ${defaultZone:http://127.0.0.1:10086/eureka}
    #      register-with-eureka: false  # register-with-eureka: true # 默认是true ,false不注册自己,因为自己本身不提供服务
    #      fetch-registry: false  # fetch-registry: true # 默认是true 不拉取
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    EurekaApplication.class

    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaApplication.class,args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.User-service配置

    pom.xml

    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>cloud-demoartifactId>
            <groupId>com.cheunggroupId>
            <version>1.0-SNAPSHOTversion>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>user-serviceartifactId>
    
        <properties>
            <maven.compiler.source>8maven.compiler.source>
            <maven.compiler.target>8maven.compiler.target>
        properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
            dependency>
            
            <dependency>
                <groupId>org.mybatis.spring.bootgroupId>
                <artifactId>mybatis-spring-boot-starterartifactId>
                <version>2.2.2version>
            dependency>
    
            <dependency>
                
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
            dependency>
        dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
            plugins>
        build>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    application.yml

    server:
      port: 8081
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
        username: root
        password: *****
        driver-class-name: com.mysql.cj.jdbc.Driver
      application:
        name: user-service
    mybatis:
      type-aliases-package: cn.cheung.user.pojo
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        cn.cheung: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:10086/eureka # 注册地址
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    UserApplication.class

    @MapperScan("cn.cheung.user.mapper")
    @SpringBootApplication
    public class UserApplication {
        public static void main(String[] args) {
            SpringApplication.run(UserApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    UserController.class

    @Slf4j
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
        
        @GetMapping("/{id}")
        public User queryById(@PathVariable("id") Long id) {
            return userService.queryById(id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.Order-service配置

    pom.xml

    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>cloud-demoartifactId>
            <groupId>com.cheunggroupId>
            <version>1.0-SNAPSHOTversion>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>order-serviceartifactId>
    
        <properties>
            <maven.compiler.source>8maven.compiler.source>
            <maven.compiler.target>8maven.compiler.target>
        properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
            dependency>
            
            <dependency>
                <groupId>org.mybatis.spring.bootgroupId>
                <artifactId>mybatis-spring-boot-starterartifactId>
                <version>2.2.2version>
            dependency>
    
            <dependency>
                
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
            dependency>
        dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
            plugins>
        build>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    application.yml

    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
        username: root
        password: ******
        driver-class-name: com.mysql.cj.jdbc.Driver
      application:
        name: order-service
    mybatis:
      type-aliases-package: cn.cheung.user.pojo
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        cn.cheung: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:10086/eureka
    #ribbon:
    #  eager-load: # ribbon饥饿加载(创建LoadBalanceClient)
    #    clients: user-service
    #    enabled: true # 默认是false 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    OrderService.class

    @Service
    public class OrderService {
    
        @Autowired
        private OrderMapper orderMapper;
    
    
        @Autowired
        private RestTemplate restTemplate;
        public Order queryOrderById(Long orderId) {
            // 1.查询订单
            Order order = orderMapper.findById(orderId);
            // 2.url地址
    //        String url = "http://locakhost:8081/user/"+order.getUserId();
            String url = "http://user-service/user/"+order.getUserId();
            //调用
            User user = restTemplate.getForObject(url, User.class);
            order.setUser(user);
            // 4.返回
            return order;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    OrderController.class

    @RestController
    @RequestMapping("order")
    public class OrderController {
    
       @Autowired
       private OrderService orderService;
    
        @GetMapping("{orderId}")
        public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
            // 根据id查询订单并返回
            return orderService.queryOrderById(orderId);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5.效果

    http://locahost:8080/order/101 会调取user-service服务,查询到user信息,一定显示在客户端

    6.Eureka的负载均衡(Ribbon负载均衡)

    实现:在OrderController.class中采用注解@LoadBalanced

    @Bean
        @LoadBalanced   //拦截restTemplate发出的请求
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Ribbon负载均衡源码调用如下图:

    在这里插入图片描述

    基本流程如下(默认是轮询策略):
    • 拦截我们的RestTemplate请求http://userservice/user/1
    • RibbonLoadBalancerClient会从请求url中获取服务名称,也就是user-service
    • DynamicServerListLoadBalancer根据user-service到eureka拉取服务列表
    • eureka返回列表,localhost:8081、localhost:8082
    • IRule利用内置负载均衡规则,从列表中选择一个,例如localhost:8081
    • RibbonLoadBalancerClient修改请求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,发起真实请求
    Ribbon负载均衡策略
    • 负载均衡策略都定义在IRule接口中,而IRule中有很多不同的实现类,如下图:
      在这里插入图片描述
      不同规则的含义如下:
    内置负载均衡规则类规则描述
    RoundRobinRule简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。
    AvailabilityFilteringRule对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。
    WeightedResponseTimeRule为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
    ZoneAvoidanceRule以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。
    BestAvailableRule忽略那些短路的服务器,并选择并发数较低的服务器。
    RandomRule随机选择一个可用的服务器。
    RetryRule重试机制的选择逻辑
    修改负载均衡策略(一般不进行修改):
    • 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则:
    userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 
    
    • 1
    • 2
    • 3
    Ribbon饥饿加载

    Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。
    而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

    ribbon:
      eager-load:
        enabled: true
        clients: user-service
    
    • 1
    • 2
    • 3
    • 4

    Nacos

    阿里巴巴技术,SpringCloudAlibaba也推出了一个名为Nacos的注册中心。

    1.Nacos-server可视化客户端安装

    [资源地址]安装(https://github.com/alibaba/nacos/releases):

    • 我下载的是1.4.4版本点击下载 2.1.x版本我无法使用,不知道为何
    • 下载完解压,进入bin目录(我将nacos放在了 /usr/local/nacos中)
    • 进入终端输入:sh startup.sh -m standalone
    • 进入:localhost:8848/nacos
    • 账号密码都是:nacos
    • 关闭:sh shutdown.sh

    Nacos依赖

    父依赖:
    <dependencyManagement>
            <dependencies>
    
                <dependency>
                    <groupId>com.alibaba.cloudgroupId>
                    <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                    <version>2.1.0.RELEASEversion>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
    
            dependencies>
        dependencyManagement>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    客户端依赖:
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.配置修改

    pom.xml添加以上nacos客户端依赖,注释掉Eureka依赖

    application.yml(注释掉Eureka部分,添加如下部分,User-service、Order-service同样)

    spring:
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
            cluster-name: JS # 集群名称
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.配置集群

     cluster-name: JS # 集群名称
    
    • 1

    同一个集群优先的负载均衡

    修改负载均衡规则

    • 修改order-service的application.yml文件,修改负载均衡规则:
    user-service:
      ribbon:
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则 
    
    • 1
    • 2
    • 3

    权重配置

    场景:同一个集群中注册了多个同样的实例,会进行同一个集群优先负载均衡,但是由于个别实例机器性能差,所以需进行权重配置,来控制各个实例的访问频率,权重越大访问频率越高。
    修改步骤:

    在这里插入图片描述
    在弹出的窗口进行修改:
    在这里插入图片描述

    4.环境隔离

    Nacos提供了namespace来实现环境隔离功能。

    • nacos中可以有多个namespace
    • namespace下可以有group、service等
    • 不同namespace之间相互隔离,例如不同namespace的服务互相不可见
      在这里插入图片描述

    创建命名空间

    默认情况下,所有service、data、group都在同一个namespace,名为public:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    就能在页面看到一个新的namespace:
    在这里插入图片描述

    给微服务配置namespace

    给微服务配置namespace只能通过修改配置来实现。
    例如,修改order-service的application.yml文件:

    spring:
      cloud:
        nacos:
          discovery:
    	    server-addr: localhost:8848
            cluster-name: HZ
            namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    重启order-service后,访问控制台,可以看到下面的结果:
    在这里插入图片描述
    此时访问order-service,因为namespace不同,会导致找不到userservice,控制台会报错:
    在这里插入图片描述

    Eureka 和 Nacos的区别

    Nacos的服务实例分为两种l类型:

    • 临时实例:如果实例宕机超过一定时间(30s),会从服务列表剔除,默认的类型。(微服务向nacos发送心跳)
    • 设置为临时实例 只占用nacos内存,不写入nacos磁盘,实例自动向nacos-server发送心跳
    • 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。(nacos向微服务主动询问)
    • 设置为非临时实例 不仅占用nacos内存,还会写入nacos磁盘,nacos-server主动向实例发送询问
    spring:
      cloud:
        nacos:
          discovery:
           ephemeral: false # 设置为非临时实例 不仅占用nacos内存,还会写入nacos磁盘,nacos-server主动向client发送询问
    #        ephemeral: ture # 设置为临时实例  只占用nacos内存,不写入nacos磁盘,自动向nacos-server发送心跳
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Nacos和Eureka整体结构类似,服务注册、服务拉取、心跳等待,但是也存在一些差异:

    在这里插入图片描述

    • Nacos与eureka的共同点

      • 都支持服务注册和服务拉取
      • 都支持服务提供者心跳方式做健康检测
    • Nacos与Eureka的区别

      • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
      • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
      • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
      • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
        • A(可用性) C(一致性) P(分区容错)
        • nacos违背了可用性A,只满足一致性C和分区容错P时,即CP
  • 相关阅读:
    力扣第310场周赛总结与反思
    深度分析:Apache Hadoop及其在大数据处理中的应用
    yolov7和yolov5对比有哪些优势?yolov7改进-yolov7详解
    资产管理5大漏洞,你中了几个?
    ffmpeg把视频文件转码为MP4格式
    GitHub 忘记SSH密钥
    Apple developer证书、标识符和描述文件
    excel表导出
    使用docker安装db2
    【二】数据库系统
  • 原文地址:https://blog.csdn.net/weixin_44519169/article/details/126574060