zoukankan      html  css  js  c++  java
  • 第二篇:服务消费者Feign

    一  Feign简介

    Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。

    简而言之:

    • Feign 采用的是基于接口的注解
    • Feign 整合了ribbon,具有负载均衡的能力
    • 整合了Hystrix,具有熔断的能力

    二  准备工作

    继续用上一节的工程, 启动eureka-server,端口为8060;

    三  创建两个feign的服务callcenter-user和callcenter-freeswitch

    新建一个spring-boot Module ,取名为callcenter-user,在它的pom文件引入Feign的起步依赖spring-cloud-starter-feign、Eureka的起步依赖spring-cloud-starter-netflix-eureka-client、Web的起步依赖spring-boot-starter-web,代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.hmzj</groupId>
        <artifactId>callcenter-user</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>callcenter-user</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>

    在工程的配置文件application.yml文件,指定程序名为callcenter-user,端口号为8050,服务注册地址为http://127.0.0.1:8060/eureka/ ,代码如下:

    server:
      port: 8051
    spring:
      application:
        name: callcenter-user
    eureka:
      instance:
        prefer-ip-address: true
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
        # 心跳检测检测与续约时间
        # 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
        lease-renewal-interval-in-seconds: 1 # lease-renewal-interval-in-seconds 每间隔1s,向服务端发送一次心跳,证明自己依然”存活“
        lease-expiration-duration-in-seconds: 2 #lease-expiration-duration-in-seconds  告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
      client:
        serviceUrl:
          defaultZone: http://userName:password@127.0.0.1:8060/eureka/ #服务注册时的账号和密码

    在程序的启动类CallcenterUserApplication,加上@EnableFeignClients注解开启Feign的功能:

    @EnableFeignClients
    @EnableDiscoveryClient //也可以使用@EnableEurekaClient 
    @SpringBootApplication
    public class CallcenterUserApplication { public static void main(String[] args) { SpringApplication.run(CallcenterUserApplication.class, args); } }

    新建一个spring-boot Module ,取名为callcenter-freeswitch,在它的pom文件引入Feign的起步依赖spring-cloud-starter-feign、Eureka的起步依赖spring-cloud-starter-netflix-eureka-client、Web的起步依赖spring-boot-starter-web,代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hmzj</groupId>
    <artifactId>callcenter-freeswitch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>callcenter-freeswitch</name>
    <description>Demo project for Spring Boot</description>

    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
    <dependency>
    <groupId>com.hmzj</groupId>
    <artifactId>callcenter-utils</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>

    <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>${spring-cloud.version}</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    </dependencies>
    </dependencyManagement>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>


    </project>

    在工程的配置文件application.yml文件,指定程序名为callcenter-freeswitch,端口号为8052,服务注册地址为http://127.0.0.1:8060/eureka/ ,代码如下:

    server:
      port: 8052
    spring:
      application:
        name: callcenter-freeswitch
    eureka:
      instance:
        prefer-ip-address: true
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
        # 心跳检测检测与续约时间
        # 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
        lease-renewal-interval-in-seconds: 1 # lease-renewal-interval-in-seconds 每间隔1s,向服务端发送一次心跳,证明自己依然”存活“
        lease-expiration-duration-in-seconds: 2 #lease-expiration-duration-in-seconds  告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
      client:
        serviceUrl:
          defaultZone: http://userName:password@127.0.0.1:8060/eureka/ #服务注册时的账号和密码

    在程序的启动类CallcenterFreeswitchApplication,加上@EnableFeignClients注解开启Feign的功能:

    @EnableFeignClients
    @EnableDiscoveryClient //也可以使用@EnableEurekaClient 
    @SpringBootApplication
    public class CallcenterFreeswitchApplication{
    public static void main(String[] args) {
    SpringApplication.run(CallcenterFreeswitchApplication.class, args);
    }
     }

    四 微服务之间的调用示例

     

    在callcenter-user根目录下创建package 叫controller 创建TestController:

    package com.hmzj.callcenteruser.controller;
    
    import com.hmzj.callcenteruser.entry.User;
    import com.hmzj.callcenteruser.service.FreeswitchService;
    import com.hmzj.callcenteruser.service.UserService;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author Yangqi.Pang
     * @version V0.0.1
     */
    @RestController
    @RefreshScope
    @RequestMapping("test")
    public class TestConteoller {
    
            private FreeswitchService freeswitchService;
            private UserService userService;
    
            public TestConteoller(FreeswitchService freeswitchService, UserService userService) {
                    this.freeswitchService = freeswitchService;
                    this.userService = userService;
            }
    
            @Value("${server.port}")
            String port;
    
    
            @GetMapping("sayHello/{userName}")
            public String sayHello(@PathVariable String userName){
                return "hello "+userName+"I'm come from user my port :"+port;
            }
    
            @GetMapping("saveUser")
            public void saveUser(User user){
                   userService.saveUser(user);
            }
    
            @GetMapping("freeswitchSayHi/{userName}")
            public String freeswitchSayHi(@PathVariable String userName){
                    return freeswitchService.sayHi(userName);
            }
    }


    在callcenter-user根目录下创建package 叫service创建FreeswitchService:

    package com.hmzj.callcenteruser.service;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.stereotype.Service;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /**
     * @author Yangqi.Pang
     * @version V0.0.1
     */
    @FeignClient(value = "callcenter-freeswitch")
    @Service
    public interface FreeswitchService {
    
        @GetMapping("/test/sayHi/{userName}")
        String sayHi(@PathVariable(value = "userName") String userName);
    }

    此处的@FeignClient注解里的value值就是调用的服务名称

    在callcenter-freeswitch根目录下创建package 叫controller 创建TestController:

    package com.hmzj.callcenterfreeswitch.controller;
    
    import com.hmzj.callcenterfreeswitch.entry.User;
    import com.hmzj.callcenterfreeswitch.service.FreeSwitchService;
    import com.hmzj.callcenterfreeswitch.service.UserService;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author Yangqi.Pang
     * @version V0.0.1
     */
    @RestController
    @RequestMapping("test")
    public class TestController {
    
        private UserService userService;
    
        private FreeSwitchService freeSwitchService;
    
        public TestController(UserService userService, FreeSwitchService freeSwitchService) {
            this.userService = userService;
            this.freeSwitchService = freeSwitchService;
        }
    
    
    
        @Value("${server.port}")
        String port;
    
        @GetMapping("sayHi/{userName}")
        public String sayHi(@PathVariable String userName){
            return "hi "+userName+"I'm come from freeswitch my port :"+port;
        }
    
        @GetMapping("saveUser")
        public void saveUser(User user){
            freeSwitchService.saveUser(user);
        }
    
        @GetMapping("userSayHello/{userName}")
        public String userSayHello(@PathVariable String userName){
            return userService.sayHello(userName);
        }
    }

    启动服务callcenter-user:

    启动服务callcenter-freeswitch:

    访问 http://localhost:8051/test/sayHello/pyq 浏览器会显示

      hello pyqI'm come from user my port :8051   

      这个是调用8051端口 的服务  还没有跨服务调用

    接下来访问 http://localhost:8051/test/freeswitchSayHi/pyq 浏览器会显示

      hi pyqI'm come from freeswitch my port :8052   

      这个是调用8052端口的服务  跨服务调用

    五   检测Feign的负载均衡

    再次启动服务callcenter-freeswitch端口号为8053:

     idea中可以启动多个示例的方式

     

     

     访问http://localhost:8051/test/freeswitchSayHi/pyq 浏览器会显示

     

        

        端口号交替出现

  • 相关阅读:
    json格式转换
    早该知道的7个JavaScript技巧
    SPFA加上SLF时判负环的条件
    HDU 4061 A Card Game
    线性筛法求素数
    STL之deque
    POJ 3219 二项式系数
    HDU 4296 Buildings
    HDU 4292 Food (成都赛区网络赛第五题,拆点网络流)
    拆点网络流(POJ3281)
  • 原文地址:https://www.cnblogs.com/pangyangqi/p/9390790.html
Copyright © 2011-2022 走看看