• springboot10-springcloud-eureka 服务注册与发现,负载均衡客户端(ribbon,feign)调用


    创建5个项目:

    1.服务注册中心

    2.服务提供者1

    3.服务提供者2(与服务提供者1的代码实现一样,这是是为了模拟负载均衡)

    4.ribbon客户端项目

    5.feign客户端项目

    如图:


    一、注册中心项目:

    pom文件中添加:

    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
            </dependency>

    启动类:

    /**
     * MainApp类描述: 服务注册中心
     *
     * @author yangzhenlong
     * @since 2017/3/16
     */
    @EnableEurekaServer//注解启动一个服务注册中心
    @SpringBootApplication
    public class RegisterMainApp {
    
        public static void main(String[] args) {
            SpringApplication.run(RegisterMainApp.class, args);
        }
    }

    application配置文件:

    server.port=8888
    
    #在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为
    eureka.client.register-with-eureka=false
    eureka.client.fetch-registry=false
    
    #服务注册地址
    eureka.instance.ip-address=localhost
    eureka.instance.prefer-ip-address=true
    eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

    然后启动项目,访问:http://localhost:8888/

    这时候发现,Application下面是空的,因为还没有服务注册进来


    2.服务提供1

    pom文件:

    启动类:

    /**
     * MainApp类描述: 服务提供
     *
     * @author yangzhenlong
     * @since 2017/3/16
     */
    @EnableDiscoveryClient//激活Eureka中的DiscoveryClient实现
    @SpringBootApplication
    public class ProviderMainApp {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderMainApp.class, args);
        }
    }

    提供的rest接口类:

     1 package com.eureka.rest;
     2 
     3 
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.cloud.client.ServiceInstance;
     8 import org.springframework.cloud.client.discovery.DiscoveryClient;
     9 import org.springframework.web.bind.annotation.PathVariable;
    10 import org.springframework.web.bind.annotation.RequestMapping;
    11 import org.springframework.web.bind.annotation.RestController;
    12 
    13 import java.util.List;
    14 
    15 /**
    16  * UserController类描述:
    17  *
    18  * @author yangzhenlong
    19  * @since 2017/4/13
    20  */
    21 @RestController()
    22 public class UserController {
    23 
    24     private final static Logger LOGGER = LoggerFactory.getLogger(UserController.class);
    25     @Autowired
    26     private DiscoveryClient discoveryClient;
    27 
    28     @RequestMapping("/")
    29     public String index(){
    30         return "index";
    31     }
    32 
    33     @RequestMapping("/client")
    34     public String client(){
    35         String description = discoveryClient.description();
    36         ServiceInstance localServiceInstance = discoveryClient.getLocalServiceInstance();
    37         List<String> services = discoveryClient.getServices();
    38         StringBuffer sb = new StringBuffer();
    39         sb.append("discoveryClient描述:" + description);
    40         sb.append("
    discoveryClient本地服务HOST:" + localServiceInstance.getHost() + "---port:" + localServiceInstance.getPort() + "---serverId:" +localServiceInstance.getServiceId());
    41         sb.append("
    discoveryClient services:" + services);
    42         return "discoveryClient:" + sb.toString();
    43     }
    44 
    45     @RequestMapping("/{id}")
    46     public String get(@PathVariable String id){
    47         logCurrServerInfo();
    48         return discoveryClient.getLocalServiceInstance().getHost()
    49                 + discoveryClient.getLocalServiceInstance().getPort()
    50                 + "<hr/>用户:" + id;
    51     }
    52 
    53     @RequestMapping("/add/{name}")
    54     public String add(@PathVariable String name){
    55         logCurrServerInfo();
    56         return discoveryClient.getLocalServiceInstance().getHost()
    57                 + discoveryClient.getLocalServiceInstance().getPort()
    58                 + "<hr/>添加用户:" + name;
    59     }
    60 
    61     @RequestMapping("/getAll")
    62     public String add(){
    63         logCurrServerInfo();
    64         String s = "";
    65         for(int i=1; i<=5; i++){
    66             s = s + i + "测试测试" + System.currentTimeMillis() + "
    ";
    67         }
    68         return discoveryClient.getLocalServiceInstance().getHost()
    69                 + discoveryClient.getLocalServiceInstance().getPort()
    70                 + "<hr/>所有用户:" + s;
    71     }
    72     private void logCurrServerInfo(){
    73         LOGGER.info("当前服务信息------
     ServiceId:{}, 
     Host:{},
     Port:{}",
    74                 discoveryClient.getLocalServiceInstance().getServiceId(),
    75                 discoveryClient.getLocalServiceInstance().getHost(),
    76                 discoveryClient.getLocalServiceInstance().getPort()
    77         );
    78     }
    79 
    80 }
    View Code

    application配置:

    server.port=1111
    server.address=localhost
    spring.application.name=provider
    
    #注册中心地址
    eureka.instance.ip-address=localhost
    eureka.instance.prefer-ip-address=true
    eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka/

    然后启动该项目,这时候看见注册中心console打印信息:有服务为provider端口为1111的服务注册进来了

    再刷新http://localhost:8888/注册中心页面,发现application中有注册进来一个服务,名称为PROVIDER

    这样第一个服务就注册完成了


    3.服务提供者2(这里为了模仿负载均衡,provider1项目的代码拷贝一份,修改端口为2222),和第二步类似,只是配置文件中,设置端口为:2222

    启动服务,查看注册服务console:

    刷新注册中心地址,发现2个服务注册到同一个服务名称,只是端口不一样


    4.ribbon http客户端

    pom文件中加入eureka和ribbon:

         <!--父依赖包-->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.5.RELEASE</version>
            <relativePath/>
        </parent>
    
            <!--eureka-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
            </dependency>
            <!--ribbon-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
            </dependency>

    注:这里的springboot版本要设置为1.3.x,如果设置1.4.x,启动项目的时候,会报错:

    springboot版本选择1.4.x时会报错:
    org.springframework.core.annotation.AnnotationConfigurationException: Attribute 'value' in annotation [org.springframework.cloud.netflix.feign.FeignClient] must be declared as an @AliasFor [serviceId], not [name].


    启动类:
    @EnableDiscoveryClient//发现服务
    @SpringBootApplication
    public class ClientRibbonMainApp {
    
        @Bean
        @LoadBalanced//开启均衡负载能力
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(ClientRibbonMainApp.class, args);
        }
    }
    http客户端调用:
    @RestController()
    public class RibbonController {
    
        private final static Logger LOGGER = LoggerFactory.getLogger(RibbonController.class);
        @Autowired
        private RestTemplate restTemplate;
    
        @RequestMapping("/")
        public String index(){
            return "index";
        }
    
        @RequestMapping("/add/{name}")
        public String add(@PathVariable String name){
            ResponseEntity<String> forEntity = restTemplate.getForEntity("http://PROVIDER/add/" + name, String.class);
            return forEntity.getBody();
        }
    }

    启动ClientRibbonMainApp类后,注册服务:

    这时候去访问ribbon项目:http://localhost:1234/add/12djsf

    再去查看2台服务提供者项目的控制台console:

    发现Provider2被调用了,到浏览器多次请求http://localhost:1234/add/12djsf,发现有时候会调用服务1,有时候会调用服务2,所以这里我们的负载均衡起作用了。

    ribbon客户端就完成了。。


     5.feigh http客户端
    首先pom中添加eureka和feign的依赖:
            <!--eureka-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
            </dependency>
            <!--feign-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>

    启动类:

    @EnableDiscoveryClient//发现服务
    @EnableFeignClients//开启Feign功能
    @SpringBootApplication
    public class ClientFeignMainApp {
    
        public static void main(String[] args) {
            SpringApplication.run(ClientFeignMainApp.class, args);
        }
    }

    注册服务端的类,这里使用接口注解的方式,实现rpc调用:

    @FeignClient("provider")//注册中心注册的服务名称,也就是serviceId
    public interface ProviderFeignClient {
    
        @RequestMapping("/add/{name}")
        String add(@RequestParam(value = "name") String name);
    
        @RequestMapping("/getAll")
        String getAll();
    }

    调用服务:把服务接口注入进来,直接使用接口中的方法实现rpc

    @RestController
    public class FeignController {
    
        private final static Logger LOGGER = LoggerFactory.getLogger(FeignController.class);
        @Autowired
        private ProviderFeignClient providerFeignClient;
        @RequestMapping("/feign")
        public String index(){
            String all = providerFeignClient.getAll();
            return "------" + all;
        }
    
    }

    启动ClientFeignMainApp类

    浏览器访问:http://localhost:1233/feign

     发现有时候调用服务1,有时候调用服务2,这里用feign也能实现http负载均衡。

    代码地址:https://github.com/yangzhenlong/mySpringBootDemo

  • 相关阅读:
    顺序栈的模拟
    Maven安装教程详解
    C# CRC
    Oracle知识分类之常见规范
    Oracle知识分类之异常
    el-tree树结构的数据封装
    sessionStorage和localStorage
    el-form 中为el-input 添加正则校验 以及el-input正则限制
    动态组件与父子传值的灵活应用 ref控制子组件 props,emit传值
    el-tree树组件的封装 (运用递归对接口返回当前菜单数据为对象处理)
  • 原文地址:https://www.cnblogs.com/yangzhenlong/p/6710187.html
Copyright © 2020-2023  润新知