zoukankan      html  css  js  c++  java
  • 服务注册与发现及其优雅停服

    在Spring Cloud中,开发Eureka Client组件还是非常方便的。

    一、服务注册(服务提供者)

    pom依赖:

    <dependencies>
        <!-- eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- actuator监控信息
             actuator 组件是Spring Boot的监控组件,actuator一旦应用,在启动的时候,会发布一系列的URL服务。包含一个shutdown服务,代表优雅关闭。
             当Spring Boot 应用中的actuator组件接收到shutdown请求的时候,会触发优雅关闭。
             如果当前应用中有Eureka Client的集成,则会触发Eureka Client向Eureka Server发起一个shutdown优雅停服的请求-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>microservicecloud</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering><!--开启过滤-->
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <delimiters>
                        <delimit>$</delimit><!---解析以$开始和$结尾且在src/main/resources目录下的配置信息-->
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>
    View Code

    全局配置:

      在配置Eureka Server信息时,建议将Eureka Server集群中的所有节点依次配置,Eureka Client在注册服务的时候,会根据节点列表依次访问Eureka Server集群节点,只要注册成功,后续Eureka Server节点不再访问注册。虽然Eureka Server集群各节点可以相互发现服务,但是Eureka Server集群中每个节点对服务的管理都使用连带责任,及从某Eureka Server节点发现服务A,如果这个Eureka Server节点宕机,则A服务同时从服务列表中删除。

    # 定义SpringBoot应用的名称,建议必须提供。在SpringCloud中,对服务的最大粒度的管理是使用应用命名的
    # 最好是一个应用一个名称,在Consumer角色开发的时候,比较容易查找Provider
    spring.application.name=appService-name
    server.port=8888
    #eureka微服务实例名称修改,不采用默认的, 默认是spring.application.name的大写
    eureka.instance.instance-id=appService-minsoft
    
    # 配置Eureka Server的地址信息,如果是Eureka Server集群,多个节点使用逗号','分割。
    # 如果开启了安全认证,使用HTTP Bacic格式提供用户名和密码。
    # 如果Eureka Server是一个集群,那么配置Eureka Server节点信息的时候,建议将所有的Eureka Server节点信息都配置上
    # 实际上,只配置一个Eureka Server节点其实就可以了,但是,Eureka Server对服务的管理有连带责任。如果只配置一个Eureka Server节点,那么会导致级联删除的风险,可能导致服务不可靠
    # 如果配置了多个Eureka Server节点,Eureka不会将当期的服务同时注册到所有Eureka Server节点上
    # 从第一个配置的Eureka Server节点开始注册,如果注册成功,后续的Eureka Server节点不再重复注册
    # 每30秒,Eureka Client发送一个心跳到Eureka Server上,如果心跳没有反馈,则从已配置的Eureka Server节点列表的下一个服务节点继续注册。
    # 这样做可以保证服务的可靠性,降低服务连带责任导致的服务不可靠。
    # 如果多个Eureka Client需要注册,建议Eureka Server的服务列表顺序是随机排列的。
    # 如:有Eureka Server s1,s2,s3,有Eureka Client c1,c2,c3。
    # 那么在c1上配置的Eureka Server列表建议是s1,s2,s3,在c2上配置的是s2,s3,s1,在c3上配置的是s3,s1,s2,这样可以更好的利用Eureka Server集群的特性。
    # 因为Eureka Server和Eureka Client对心跳的监测都是3*间隔时间的,所以会有服务列表数据的不同步可能。
    # 所以在CAP原则上,Eureka Server是保证AP原则,放弃C原则的。
    # 注意:多个地址之间不要有多余的空格, 只有一个逗号
    eureka.client.serviceUrl.defaultZone=http://admin:1234@eurekaserver1:8761/eureka/,http://admin:1234@eurekaserver2:8761/eureka/
    
    #启动所有端点, 也可以设置部分启动, 如:env,beans。默认是health, info
    management.endpoints.web.exposure.include=*
    ## 启用shutdown,优雅停服功能,配置actuator的优雅关闭
    ## actuator 组件监听shutdown请求地址的时候,要求请求的method必须是POST
    ## shutdown的请求地址是使用:@PostMapping或@RequestMapping(method=RequestMethod.POST)
    management.endpoint.shutdown.enabled=true
    
    #访问信息可以使用IP地址
    eureka.instance.prefer-ip-address=true
    # 对该微服务进行简单的信息介绍, 随便配置
    info.app.name=appService-name
    info.company.name=myApplication
    info.build.artifactId=$project.artifactId$
    info.build.version=$project.version$
    View Code

      建议:如果有多个服务功能需要注册,那么在设置Eureka Server信息的时候,推荐异序排列。如:现在有3个工程A、B、C需要注册服务到Eureka Server集群中,集群节点有三个,分别是e1、e2、e3,那么在工程中推荐配置为,A工程配置-e1,e2,e3,B工程配置e2,e3,e1,C工程配置e3,e1,e2。这样可以更好的利用Eureka Server集群的特性。

      这里使用的是8888端口,需要在防火墙打开。

    启动类:

      需要在启动类上新增注解@EnableEurekaClient,代表当前应用开启Eureka客户端,应用启动后,会自动将服务注册到Eureka Server中。

      @EnableEurekaClient和@EnableDiscoveryClient的区别?@EnableDiscoveryClient注解是基于spring-cloud-commons依赖,并且在classpath中实现;而@EnableEurekaClient注解是基于spring-cloud-netflix依赖,只能为eureka作用。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @EnableDiscoveryClient
    @SpringBootApplication
    public class AppService {
        public static void main(String[] args) {
            SpringApplication.run(AppService.class, args);
        }
    }

    对外接口: 

    @Controller
    public class TestApplicationServiceController {
    
        @RequestMapping("/test")
        @ResponseBody
        public List<Map<String, Object>> test(){
            List<Map<String, Object>> result = new ArrayList<>();
            for(int i = 0; i < 3; i++){
                Map<String, Object> data = new HashMap<>();
                data.put("id", i+1);
                data.put("name", "test name " + i);
                data.put("age", 20+i);
                result.add(data);
            }
            return result;
        }
    }

    二、服务发现(服务消费者)

    在Spring Cloud中,服务消费方代码的开发确实比较麻烦,并不像Dubbo那么直接注入服务接口代理对象,通过代理对象方法直接访问远程服务。在Spring Cloud中,微服务的提供是通过REST风格提供的,也就是服务的调用是基于HTTP协议的,所以在服务调用上比较麻烦。

    pom依赖:

      同服务提供者。

    全局配置:

      在Eureka Server中,对服务的管理是基于spring应用名称的,所以不同的服务推荐使用不同的应用名称。

    # 定义SpringBoot应用的名称,建议必须提供。
    spring.application.name=app-client
    server.port=8111
    
    # 任何Eureka Client都必须注册。如果没有配置Eureka Server节点列表,则注册失败。Eureka client无法正常启动。
    # 注意:多个地址之间不要有多余的空格, 只有一个逗号
    eureka.client.serviceUrl.defaultZone=http://admin:1234@192.168.178.5:8761/eureka/,http://admin:1234@192.168.178.6:8761/eureka/
    
    # 设置负载均衡策略 appservice-name为调用的服务的名称
    # 没有配置全部服务的负载均衡策略的方式。因为不是每个服务都可以使用相同负载均衡策略的。
    # 如:搜索服务和注册服务就不能使用相同的负载均衡策略。
    appservice-name.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
    
    # 配置服务列表,其中appservice-name代表要访问的服务的应用名,如果有多个服务结点组成集群,多个节点的配置信息使用逗号','分隔。
    # 配置服务列表,需要配置要调用的服务的名字和服务所在的位置。
    # 服务的名字,就是Application Service(服务提供者)中配置的spring.application.name。
    # 服务的位置,就是服务的所在ip和端口。
    # 如果服务位置有多个,也就是服务集群,那么使用逗号','分割多个服务列表信息。
    appservice-name.ribbon.listOfServers=192.168.178.5:8888
    View Code

    启动类:

    @EnableDiscoveryClient
    @SpringBootApplication
    public class AppClient {
        public static void main(String[] args) {
            SpringApplication.run(AppClient.class, args);
        }
    }

    请求调用类(并不是只有这一种方式):

    /**
     * 在这里开发Eureka Client中的Application Client角色。就是consumer服务的消费者。
     * 服务消费者需要在注册中心中发现服务列表的。且同时将自己注册到注册中心的服务列表中。(参考如下截图)
     * 
     * consumer在消费provider的时候,是通过LoadBalancer来实现的。
     * LoadBalancer简介 : 是Eureka client内置的一个负载均衡器。复杂在发现的服务列表中选择服务应用,获取服务的IP和端口。
     * 实现服务的远程调用。
     * 
     * application client代码开发相比较dubbo的consumer开发麻烦很多。
     * 
     */
    @RestController
    public class TestApplicationClientController {
    
        /**
         * ribbon负载均衡器,其中记录了从Eureka Server中获取的所有服务信息。 
         * 这些服务的信息是IP和端口等。应用名称,域名,主机名等信息。
         */
        @Autowired
        private LoadBalancerClient loadBalancerClient;
    
        /**
         * 通过HTTP协议,发起远程服务调用,实现一个远程的服务消费。
         * @return
         */
        @GetMapping
        public List<Map<String, Object>> test() {
    
            // 通过spring应用命名,获取服务实例ServiceInstance对象
            // ServiceInstance 封装了服务的基本信息,如 IP,端口
            /*
             * 在Eureka中,对所有注册到Eureka Server中的服务都称为一个service instance服务实例。
             * 一个服务实例,就是一个有效的,可用的,provider单体实例或集群实例。
             * 每个service instance都和spring application name对应。
             * 可以通过spring application name查询service instance
             */
            ServiceInstance si = this.loadBalancerClient.choose("appservice-name");
            // 拼接访问服务的URL
            StringBuilder sb = new StringBuilder();
            // http://192.168.178.6:8761/test
            sb.append("http://").append(si.getHost())
                .append(":").append(si.getPort()).append("/test");
    
            System.out.println("本次访问的service是: " + sb.toString());
            
            // SpringMVC RestTemplate,用于快速发起REST请求的模板对象。
            /*
             * RestTemplate是SpringMVC提供的一个用于发起REST请求的模板对象。
             * 基于HTTP协议发起请求的。
             * 发起请求的方式是exchange。需要的参数是: URL, 请求方式, 请求头, 响应类型,【URL rest参数】。
             */
            RestTemplate rt = new RestTemplate();
    
            /*
             * 创建一个响应类型模板。
             * 就是REST请求的响应体中的数据类型。
             * ParameterizedTypeReference - 代表REST请求的响应体中的数据类型。
             */
            ParameterizedTypeReference<List<Map<String, Object>>> type =
                    new ParameterizedTypeReference<List<Map<String, Object>>>() {
            };
    
            /*
             * ResponseEntity:封装了返回值信息,相当于是HTTP Response中的响应体。
             * 发起REST请求。
             */
            ResponseEntity<List<Map<String, Object>>> response =
                    rt.exchange(sb.toString(), HttpMethod.GET, null, type);
            /*
             * ResponseEntity.getBody() - 就是获取响应体中的java对象或返回数据结果。
             */
            List<Map<String, Object>> result = response.getBody();
    
            return result;
        }
    
    }
    View Code

    LoadBanlancerClient中包含了所有的服务注册信息。

    三、优雅关闭服务(优雅停服)

    在Spring Cloud中,可以通过HTTP请求的方式,通知Eureka Client优雅停服,这个请求一旦发送到Eureka Client,那么Eureka Client会发送一个shutdown请求到Eureka Server,Eureka Server接收到这个shutdown请求后,会在服务列表中标记这个服务的状态为down,同时Eureka Client应用自动关闭。这个过程就是优雅停服。

    如果使用了优雅停服,则不需要再关闭Eureka Server的服务保护模式。

    POM依赖:优雅停服是通过Eureka Client发起的,所以需要在Eureka Client中增加新的依赖,这个依赖是autuator组件,添加下述依赖即可。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    修改全局配置文件:Eureka Client默认不开启优雅停服功能,需要在全局配置文件中新增如下内容:

    #启动所有端点, 也可以设置部分启动, 如:env,beans。默认是health, info
    management.endpoints.web.exposure.include=*
    # 启用shutdown,优雅停服功能
    management.endpoint.shutdown.enabled=true

    发起shutdown请求:

      必须通过POST请求向Eureka Client发起一个shutdown请求。请求路径为:http://ip:port/actuator/shutdown。可以通过任意技术实现,如:HTTPClient、form表单,AJAX等。
      建议使用优雅停服方式来关闭Application Service/Application Client服务。

    参考:https://www.cnblogs.com/jing99/p/11576133.html

  • 相关阅读:
    nodejs安装以及配置
    java第三周学习总结
    java第二周学习总结
    java第一周学习总结
    调查问卷
    2016.2.19 学习总结
    第一周学习总结
    第一周学习总结
    假期马原学习计划
    20145335郝昊《java程序设计》第2次实验报告
  • 原文地址:https://www.cnblogs.com/myitnews/p/12416506.html
Copyright © 2011-2022 走看看