精华内容
下载资源
问答
  • 使用feign远程调用接口
    2021-01-12 16:59:29

    项目中开发中,经常会用到调用其他项目的接口 或者第三方接口的情况,以前经常使用的是spring 的restTemplate 或者httpClient,但是使用每次都需要写一些公共的调用代码,比较麻烦。

    feign 则能够比较好的解决了这个问题,不是spring cloud 项目也可以使用。

    一,是什么

    feign 是Netflix 开发的声明式的http客户端,可以帮我们更加方便的调用http接口。在使用时候,就像调用本地方法一样,创建一个接口,然后在接口上添加一些注解,代码就可以完成了。spring Cloud 对feign进行了增强,使feign支持spring mvc 注解,并且整合了Ribbon 和Eureka,从而让Feign的使用更加的方便。

    二,怎么用

    1.添加pom引用

    org.springframework.cloud

    spring-cloud-starter-feign

    2.启动类添加@EnableFeignClients

    @SpringBootApplication

    @EnableFeignClients

    public class DemoApplication {

    public static void main(String[] args) {

    SpringApplication.run(DemoApplication.class, args);

    }

    }

    3.创建service,添加@feignclient注解

    /**

    * @创建人

    * @创建时间 2020/12/10

    * @描述

    */

    @FeignClient(value = "spring-boot-user", url = "http://test-ns.htexam.com/pand/common/mo",

    //fallback = HystrixClientFallBack.class

    fallbackFactory = HystrixClientFallBackFactory.class)

    public interface UserFeignClient {

    @RequestMapping(value = "", method = RequestMethod.GET)

    Object findById();

    }

    @feignCient 注解中,value和name 是指定的要调用的服务ID,url是指定的访问的url地址,有时候,feignclient没有启动注册中心,那我们就需要启动feingclient中的url属性来表明被调用方。fallBack或fallBackFactory 是方法失败,可以回退调用的方法。

    首先这是一个接口,feign通过动态代理,帮助我们生成实现类,通过value 指定要要调用的服务的名称。接口中的定义的方法,通过使用spring mvc 的注解,Feign会根据注解生成url,并且返回结果。

    4.创建会退fallBack

    fallbackFactory与fallback方法不能同时使用,这个两个方法其实都类似于Hystrix的功能,当网络不通时返回默认的配置数据.

    (1)fallBackFactory 方法

    @Component

    public class HystrixClientFallBackFactory implements FallbackFactory {

    private Logger logger = LoggerFactory.getLogger(HystrixClientFallBackFactory.class);

    @Override

    public UserFeignClient create(Throwable throwable) {

    logger.error("failBack reason :{}",throwable.getMessage());

    //若发生错误,打印出来

    //failBack reason :status 404 reading UserFeignClient#findById()

    return new UserFeignClient() {

    @Override

    public Object findById() {

    StudentEntity studentEntity = StudentEntity.builder().userName("fallBackFactory 默认的用户名称").userId(456).age(12).build();

    return studentEntity;

    }

    };

    }

    }

    fallBack 回退之后,但是想要知道发生fallBack的原因,可以使用Logger打印出来,

    logger.error(“fallback reason:{}”,throwable.getMessage());

    (2)fallBack方式

    直接实现UserFeignClient接口,然后重新servie方法

    @Component

    public class HystrixClientFallBack implements UserFeignClient{

    @Override

    public Object findById() {

    StudentEntity studentEntity = StudentEntity.builder().userId(123).userName("默认的用户姓名").age(12).build();

    return studentEntity;

    }

    }

    若配置了fallback,需要yml文件中配置,将熔断打开。

    feign:

    hystrix:

    enabled: true# 开启feign的熔断功能

    #若为true,但是未配置fallBack类 FeignPaperService#getMapper() failed and no fallback available.

    为了验证测试熔断fallBack机制,我将调用接口的url 改成错误的路由,并没有走到fallback类中去,而是抛错了。

    status 404 reading UserFeignClient#findById()

    原因就是未开启 feign:hystrix:enabled=true

    5.单元测试

    @Test

    public void testFeignUserService() {

    Object object = userFeignClient.findById();

    log.info("object信息是:{}" + object);//返回的是默认的 userName

    }

    三,openFeign 和 Feign的区别

    openFeign是Feign的升级版本,相同点:都是远程调用的组件,里面度配置了ribbon,都可以进行远程调用

    不同点:一个是spring-cloud-starter-feign,一个是spring-cloud-starter-openfeign

    四, 其他功能

    其他feign还支持负载均衡,Hystrix 熔断支持,请求压缩等。

    参考链接:

    feign声明式服务调用

    feign使用大全

    更多相关内容
  • feign调用方法: @RequestMapping(value = /resources/ocircuit/textInfo, method = {RequestMethod.GET}, produces = text/plain;charset=utf-8) String getOcircuitTextRouteInfo(@PathVariable(name = resID) ...
  • 在微服务盛行的今天,做接口开发请求第三方服务的接口,大概率会用feign做请求,而feign也是最常用的一种rpc框架; 这里主要是说明在进行feign请求的时候,第三方服务的url和接口也是可以通过读取配置文件的配置,来...

    前言:
    在微服务盛行的今天,做接口开发请求第三方服务的接口,大概率会用feign做请求,而feign也是最常用的一种rpc框架;

    这里主要是说明在进行feign请求的时候,第三方服务的url和接口也是可以通过读取配置文件的配置,来进行请求的;

    至于为什么要把接口和url写在配置中呢,其实也是看需求了;
    若是该接口是作为基础服务可能会请求多个第三方使用(我们就是不同分支的代码作为独立项目部署,请求不同的客户接口),不同客户的接口地址可能不同,此时就需要做成配置方式;
    若是不常改动,其实也没必要做成配置了;

    常用方式:
    通常我们是这么请求第三方接口的:(用feign方式)

    
    @FeignClient(name = "feignCustomerService", url = "${customer.url}",configuration = FeignClientConfig.class)
    public interface FeignCustomerService {
        /**
         * 请求客户的接口
         */
        @RequestMapping(value = "order/update", method = RequestMethod.POST)
        @Headers(value = "Content-Type: application/json")
        OrderHttpResponse updateOrder(@RequestBody OrderUpdateDTO orderUpdateDTO);
    
    }
    

    说明:
    请求客户的url是读取的配置文件中的值,
    调用客户的具体的目标方法是:order/update 这个方法
    我们配置文件(yml文件):

    # 请求客户,客户的接口配置
    customer:
      url: http://127.0.0.1:8888/
        
    

    这样的话,最终请求客户这个接口的url就是:
    http://127.0.0.1:8888/order/update

    问题来了:
    这整个url可以看成两部分,一部分是ip和端口,一部分是请求的路径
    第一部分:[http://127.0.0.1:8888/]
    第二部分:[order/update]

    那其实上面我们已经把第一部分写到配置文件中了,第二部分还是写死在代码中,怎么实现第二部分也在配置中配置呢?

    方式一:@Value(“”)

    @Value(“”)
    这种方式可以读取配置文件中的值,但是我们这里都是feign接口,接口中定义的变量仅可以为static final的,
    说白了:就是要interface中的常量必须要初始化的,
    这种是动态读取的,达不到我们的要求;

    方式二:利用@PathVariable注解的特性;

    利用@PathVariable注解的特性;

    用于接收请求路径中占位符的值

    @PathVariable(“xxx”)
    通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中
    如:
    @RequestMapping(value=”user/{id}/{name}”)
    请求路径:http://localhost:8080/hello/show/1/lisi

    所以改造下我们的方法:

    
    @FeignClient(name = "feignCustomerService", url = "${customer.url}",configuration = FeignClientConfig.class)
    public interface FeignCustomerService {
        /**
         * 请求客户的接口
         */
        @RequestMapping(value = "{apiName}", method = RequestMethod.POST)
        @Headers(value = "Content-Type: application/json")
        OrderHttpResponse updateOrder(@PathVariable("apiName") String apiName, @RequestBody OrderUpdateDTO orderUpdateDTO);
    
    }
    

    然后在配置文件中增加:

    # 请求客户,客户的接口配置
    customer:
      url: http://127.0.0.1:8888/
      updateOrderApiName: order/update
      insertOrderApiName: order/insert
    

    然后再增加一个配置类,用于读取该配置:

    @Component
    @ConfigurationProperties(prefix = "customer")
    @Setter
    public class FeignConsumerConfig {
    	public String url;
    	public String updateOrderApiName;
    	public String insertOrderApiName;
    }
    

    然后就可以这样请求这个feign方法:

    @Slf4j
    @RestController
    @RequestMapping(value = "")
    public class TestController {
    
        @Autowired
        private FeignCustomerService feignCustomerService;
        
        @Autowired
        private FeignConsumerConfig feignConsumerConfig;
    
        
        @RequestMapping(value = "/testFeign", method = RequestMethod.POST)
        public void testFeign() {
    
            OrderUpdateDTO orderUpdateDTO = new OrderUpdateDTO();
            orderUpdateDTO.setOrderId(22222);
            orderUpdateDTO.setxxx(111111111);
            OrderHttpResponse orderHttpResponse = feignCustomerService.updateOrder(feignConsumerConfig.updateOrderApiName,orderUpdateDTO);
            log.info("orderHttpResponse :{}",JSONObject.toJSONString(orderHttpResponse));
        }
    }
    

    其实就是比之前的调用多了一个参数(不影响),而且这个参数会替换到url中去,变相的实现了可配置;
    最终的url:
    http://127.0.0.1:8888/order/update

    缺点:
    只是会多一个参数,我觉得不影响,客户那边接收业务参数的话,只需要接收orderUpdateDTO即可,因为我们的业务参数都是写在这个类的,对于客户和我们来说,不影响业务执行;

    方式三:利用${} 方式(也是最简单的方式)

    @FeignClient(name = "feignCustomerService", url = "${customer.url}",configuration = FeignClientConfig.class)
    public interface FeignCustomerService {
        /**
         * 请求客户的接口
         */
        @RequestMapping(value = "${customer.updateOrderApiName}", method = RequestMethod.POST)
        @Headers(value = "Content-Type: application/json")
        OrderHttpResponse updateOrder(@RequestBody OrderUpdateDTO orderUpdateDTO);
    
    }
    

    只要配置文件配置了方法名,那我们这里直接用${}的方式读取就可以了,这也是最简单的一种方式;
    建议使用这种;

    说明:
    看情况使用具体哪种方式:
    方式二:适合通用的接口,具体调用哪个接口可能由url决定,也可能由请求体中某一个参数决定,
    他们的相同点就是可以公用一个请求体的参数;

    方式三:适合不同业务不同调用不同的方法,我们只需要写上这些方法,再请求不同的方法即可。

    目前我想到的是这种方式,既可以把url可配置,请求路径也可实现可配置化,
    如果有其它方式还请留言多交流;

    展开全文
  • 主要是使用了spring的一个反射工具类ReflectionUtils 废话不多说,直接上代码 import io.lettuce.core..../*通过Class对象来获取对象中的方指定法 *第一个参数是class对象,第二个参数是方法名 *第三个参数是可变

    主要是使用了spring的一个反射工具类ReflectionUtils

    废话不多说,直接上代码
    Fegin接口如下

    @FeignClient("sys-service") 
    public interface SysFeignClient{
    
        @GetMapping("findDeptList")
        String findDeptList();
    
    	@PostMapping({"/findUserByOpNo"})
        String findUserByOpNo(@RequestParam("opNo") String opNo);
    

    核心代码

    import org.springframework.util.ReflectionUtils;
    
    String feginClass = "cn.mmy.feign.client.SysFeignClient";
    String methodName = "findDeptList";
    /*通过Class对象来获取对象中的方指定法
    *第一个参数是class对象,第二个参数是方法名
    *第三个参数是可变参数(根据需求可传可不传),需要传入参数的类型class对象(eg:String.class)
    */
    Method method = ReflectionUtils.findMethod(SpringUtil.getBean(feginClass).getClass(),methodName);
    /*执行方法
    *第一个参数是Method 对象,第二个参数是对象
    *第三个参数是可变参数(根据需求可传可不传),需要传入调用方法的参数值
    */
    Object result = ReflectionUtils.invokeMethod(method,SpringUtil.getBean(feginClass));
    System.out.println("**********--------"+result);
    

    SpringUtil如下:(在项目启动时会加载)

    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    @Component
    public class SpringUtil implements ApplicationContextAware {
    
        private static ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            if(SpringUtil.applicationContext == null) {
                SpringUtil.applicationContext = applicationContext;
            }
            System.out.println("---------------------------------------------------------------------");
    
            System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");
    
            System.out.println("---------------------------------------------------------------------");
        }
    
        //获取applicationContext
        public static ApplicationContext getApplicationContext() {
            return applicationContext;
        }
    
        //通过name获取 Bean.
        public static Object getBean(String name){
            return getApplicationContext().getBean(name);
        }
    
        //通过class获取Bean.
        public static <T> T getBean(Class<T> clazz){
            return getApplicationContext().getBean(clazz);
        }
    
        //通过name,以及Clazz返回指定的Bean
        public static <T> T getBean(String name,Class<T> clazz){
            return getApplicationContext().getBean(name, clazz);
        }
    }
    
    展开全文
  • 项目的启动顺序为 ...微服务(提供服务):节点两个【resumer-...spring-cloud-feign调用微服务(服务消费端):【resumer-feign】 1 spring-cloud-eureka 1.1 resumer-eurake-9001 resumer-eurake-9001配置文件applicat

    项目的启动顺序为
    spring-cloud-eureka 提供注册服务:节点两个【resumer-eurake-9001、resumer-eurake-9002】
    微服务(提供服务):节点两个【resumer-user、resumer-user2forTest】
    spring-cloud-feign调用微服务(服务消费端):【resumer-feign】

    1 spring-cloud-eureka
    1.1 resumer-eurake-9001
    resumer-eurake-9001配置文件application.yml:

    eureka:
      instance:
        hostname: eureka9001.com
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
           defaultZone: http://192.168.0.104:9002/eureka/
    # 关闭注册中心的自我保护机制,防止已关闭的实例无法从注册中心剔除
    #eureka.server.enable-self-preservation=false
    server:
      port: 9001
    logging:
      config: classpath:logback.xml
    
    

    启动类:EurekaApplication9001.java

    package com.asiainfo.resumer;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    @SpringBootApplication
    //激活eureka的服务端
    @EnableEurekaServer
    public class EurekaApplication9001 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaApplication9001.class, args);
        }
    }
    

    1.2 resumer-eurake-9002
    resumer-eurake-9002配置文件application.yml:

    eureka:
      instance:
        hostname: eureka9002.com
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
           defaultZone: http://192.168.0.104:9001/eureka/
    # 关闭注册中心的自我保护机制,防止已关闭的实例无法从注册中心剔除
    #eureka.server.enable-self-preservation=false
    server:
      port: 9002
    logging:
      config: classpath:logback.xml
    
    

    启动类:EurekaApplication9002.java 同EurekaApplication9001.java 一样。

    2 微服务(提供服务):节点两个【resumer-user、resumer-user2forTest】
    2.1 resumer-user 配置
    resumer-user 配置文件yml:

    server:
       port: 8002
    mybatis:
       config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
       mapper-locations:
       - classpath:mybatis/mapper/**/*.xml # mapper映射文件
       type-aliases-package: com.asiainfo.resumer # 别名类所在包
    spring:
       application:
          name: resumer-user #微服务的名字
       datasource:
          driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
          type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
          url: jdbc:mysql://localhost:3306/cloudagenttest # 数据库名称
          username: root
          password: root
          dbcp2:
             initial-size: 5 # 初始化连接数
             max-total: 5 # 最大连接数
             max-wait-millis: 200 # 等待连接获取的最大超时时间
             min-idle: 5 # 数据库连接池的最小维持连接数
    eureka:
       client:
          service-url:
             defaultZone: http://localhost:9001/eureka,http://localhost:9002/eureka
             instance:
                instance-id: resumer-user8002 #自定义服务名称信息
                prefer-ip-address: true #访问路径可以显示IP地
    
    info:
       app.name: resumer-user
       company.name: ASIAINFO
       build.artifactId: $project.artifactId$
       build.version: $project.version$
    

    注意:resumer-user #微服务的名字,将被spring-cloud-feign调用微服务(服务消费端)【resumer-feign】调用。
    启动类ProviderApplication.java

    package com.asiainfo.resumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class ProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    }
    

    控制层controller-UserController.java类

    package com.asiainfo.resumer.controller;
    import java.util.List;
    import com.asiainfo.resumer.User;
    import com.asiainfo.resumer.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
        @Autowired
        private UserService service; 
        /**
         * 测试方法
         * <p>Title: getUserTest</p>  
         * <p>Description: </p>  
         * @param id
         * @return
         */
        @CrossOrigin(origins = "*")// 支持跨域
        @RequestMapping(value="/gettest/{id}", method=RequestMethod.GET)
        public User getUserTest(@PathVariable("id") int id){
            User user = service.getUser(id);
            return user;
        }
    }
    

    业务层Service-(包括接口和实现) 和数据层dao

    package com.asiainfo.resumer.service;
    import java.util.List;
    import com.asiainfo.resumer.User;
    public interface UserService {
        public User getUser(int id);
    }
    
    package com.asiainfo.resumer.service.impl;
    import java.util.List;
    import com.asiainfo.resumer.User;
    import com.asiainfo.resumer.dao.UserDao;
    import com.asiainfo.resumer.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao; 
        @Override
        public User getUser(int id) {
            User user = userDao.getUser(id);
            System.out.println("microservice-provider微服务在响应客户端请求……");
            System.out.println("user : " + user);
            return user;
        } 
    }
    package com.asiainfo.resumer.dao;
    import java.util.List;
    import com.asiainfo.resumer.User;
    import org.apache.ibatis.annotations.Mapper;
    @Mapper
    public interface UserDao {
        public User getUser(int id);
    }
    

    数据层mybatis关联信息
    UserMapper.xml【resources/mybatis/mapper/UserMapper.xml】

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.asiainfo.resumer.dao.UserDao">
        <select id="getUser" resultType="User" parameterType="int">
            select * from user where ID=#{id}
        </select>
    </mapper>
    

    mybatis.cfg.xml【resources/mybatis/mybatis.cfg.xml】

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 开启二级缓存 -->
        <settings>
            <setting name="cacheEnabled" value="true"/>
        </settings>
    </configuration>
    

    数据库use表脚本:

    CREATE TABLE `user` (
      `ID` int(10) NOT NULL,
      `NAME` varchar(50) DEFAULT NULL,
      `AGE` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    insert into `user` (`ID`, `NAME`, `AGE`) values('1','CJ','30');
    

    2.2 resumer-user2forTest yml配置

    server:
       port: 8003
    mybatis:
       config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
       mapper-locations:
       - classpath:mybatis/mapper/**/*.xml # mapper映射文件
       type-aliases-package: com.asiainfo.resumer # 别名类所在包
    spring:
       application:
          name: resumer-user #微服务的名字
       datasource:
          driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
          type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
          url: jdbc:mysql://localhost:3306/cloudagenttest # 数据库名称
          username: root
          password: root
          dbcp2:
             initial-size: 5 # 初始化连接数
             max-total: 5 # 最大连接数
             max-wait-millis: 200 # 等待连接获取的最大超时时间
             min-idle: 5 # 数据库连接池的最小维持连接数
    eureka:
       client:
          service-url:
             defaultZone: http://localhost:9001/eureka,http://localhost:9002/eureka
             instance:
                instance-id: resumer-user8003 #自定义服务名称信息
                prefer-ip-address: true #访问路径可以显示IP地
    
    info:
       app.name: resumer-user
       company.name: ASIAINFO
       build.artifactId: $project.artifactId$
       build.version: $project.version$
    

    注意:resumer-user #微服务的名字 同 resumer-user节点名称保持一致。

    3 spring-cloud-feign调用微服务(服务消费端):【resumer-feign】
    3.1 配置文件yml

    server:
      port: 7001
    
    eureka:
      client:
        register-with-eureka: false#不在Eureka上注册与显示
        service-url:
          defaultZone: http://localhost:9001/eureka,http://localhost:9002/eureka
    

    3.2 启动类-FeignConsumerApplication

    package com.asiainfo.resumer;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients(basePackages="com.asiainfo.resumer.service")
    public class FeignConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(FeignConsumerApplication.class, args);
        }
    }
    

    RestContoller控制层-UserConsumerController

    package com.asiainfo.resumer.controller;
    import java.util.List;
    import com.asiainfo.resumer.User;
    import com.asiainfo.resumer.service.ConsumerService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class UserConsumerController {
        /**
         * test method
         * <p>Title: getTest</p>  
         * <p>Description: </p>  
         * @param id
         * @return
         */
        @RequestMapping(value="/consumer/gettest/{id}")
        public User getTest(@PathVariable("id") int id){
            User user = service.gettest(id);
            return user;
        }
    }
    

    Fegin消费服务接口-ConsumerService

    package com.asiainfo.resumer.service;
    import java.util.List;
    import com.asiainfo.resumer.User;
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    /*以后调用resumer-user微服务中的方法,只需要调用下面对应的接口既可以了*/
    @FeignClient(value="resumer-user")
    public interface ConsumerService {
        /*test*/
        @RequestMapping(value="/gettest/{id}", method=RequestMethod.GET)
        public User gettest(@PathVariable("id") int id);
    }
    

    4 运行效果
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述前台通过访问Fegin地址 http://192.168.0.104:7001/consumer/gettest/1, 刷新10次,
    resumer-feign 节点 console控制台:
    2021-06-01 13:11:57.467 INFO 12876 — [nio-7001-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client resumer-user initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=resumer-user,current list of Servers=[LAPTOP-R78VLQ0F:8003, LAPTOP-R78VLQ0F:8002],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:2; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
    },Server stats: [[Server:LAPTOP-R78VLQ0F:8002; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
    , [Server:LAPTOP-R78VLQ0F:8003; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
    ]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@26ada976

    微服务(提供服务)节点两个【resumer-user、resumer-user2forTest】 console控制台:分别响应的次数记录:
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]

    enter user2 for test web…
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    enter user2 for test web…
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    enter user2 for test web…
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]
    enter user2 for test web…
    microservice-provider微服务在响应客户端请求……
    user : User [id=1, name=CJ, age=30]

    展开全文
  • [转]http://c.biancheng.net/view/5362.html
  • 关于Feign调用报404的问题

    千次阅读 2021-08-20 00:32:37
    关于Feign调用报404的问题 一、报错信息 主要报错信息 status 404 reading XxxFeignService#methodName(Params) 可以看到这个是远程服务未找到的问题,马上检查方法的调用路由以及被调用方路由,发现没错… 诶,我...
  •   本章主要来配置一下SpringCloud中的eureka(服务注册中心)以及服务之间分别使用Ribbon和Feign调用服务,在配置之前各位小伙伴可以看一下SpringBoot和SpringCloud版本对应关系,SpringBoot和SpringCloud之间的...
  • 前言 前段时间和朋友聊天,他说他部门老大给他提了一个需求,这个需求的背景是这样...消费方feign调用时,直接通过 @FeignClient(name = "user_dev") 来进行调用,因为他们是直接把feignClient的name直接写死在代码里
  • Zuul的作用 统一将外部请求转发到具体的微服务实列上面,是...--路由网关 zuul --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netf
  • SpringCloud之Feign调用

    2020-09-19 15:41:59
    @FeignClient(name = "order-provider", fallback = OrderFallBack.class) public interface OrderClient { /** * 被调用者对应方法的路由(类和方法上的@RequestMapping) * 这里需要注意的两个地方 * 1、在这里使用...
  • 首先,我们在feign调用时,使用了FeignClient注解。#接口调用 @FeignClient("demo-service") public interface DemoServiceFeginClient { } # 开启feign @EnableFeignClients(basePackages = {"com.yxkong
  • 之前使用Ribbon的负载均衡功能,简化了远程调用时的代码,但是每次调用都需要写基本相同的代码,代码重复性高。Feign可以把Rest的请求进行隐藏,伪装成类似Controller一样,我们不需要拼接url,这些工作都可以让...
  • 定义接口 即远程调用的功能(Feign继承的ribbon的RestTemplate远程调用) 接口的实现类(Feign继承的hystrix的回调 错误降级) ItemFeignServiceFB 获取商品列表的降级方法,模拟使用缓存数据 UserFei
  • 一个外部feign接口:D 调用流程图: #mermaid-svg-kwHGreyPEnoKrPi5 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-...
  • 添加feign依赖 org.springframework.cloud spring-cloud-starter-openfeign 2.1.1.RELEASE 启动类上添加@EnableFeignClients注解 服务消费方创建Feign接口 这里是继承服务提供方提供出来的feign接口(pom文件...
  • Feign是Netflix开发的一个轻量级RESTful的HTTP服务客户端(用它来发起请求,远程调用的),是以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用Feign被广泛应用在Spring Cloud...
  • feign 调用 connection refused 解决问题: 请查看被调用的服务 uri 是否正确!!!正确配置后解决问题
  • RPC是远程过程调用(Remote Procedure Call)的缩写形式。 RPC调用流程图 客户端方法:服务调用方所调用的接口 客户端代理:将接口封装成代理对象,并序列化请求参数、反序列化响应结果,使用远程传输协议调用...
  • 可以分别调用下两个项目的服务,可以看到监控信息的变化 访问http://localhost:9000/hystrix/ 可以看到之前的配置监控地址的界面,增加http://localhost:9000/turbine.stream配置后发现出现了可视化界面,显示了两...
  • spring-cloud 原创代码例子包含服务发现、服务注册、服务路由、熔断器、feign
  • 在目前微服务的体系下,我们服务url的访问有两种,一种是从网关(gateway,zuul)路由进来,还有一种就是通过feign接口内部调用,那么结合spring-security就存在以下几种场景: 1.外部请求从gateway访问,需要鉴权(任何CURD的...
  • 远程调用 添加远程调用的依赖 yml配置文件内容 设计远程调用接口 业务层注入远程调用对象 启动类添加注解 重要注解 @EnableFeignClients注解 @FeignClient注解 zuul网关设计 添加网关设计依赖 启动类添加...
  • 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的...
  • springcloud-feign&gateway&config&bus

    千次阅读 2021-01-14 09:08:23
    feign集成了ribbon负载均衡功能,集成了hystrix熔断器功能。支持请求压缩1 使用feign替代resttemplate发送rest请求1)在consumer...feign通过动态代理生成实现类3) 控制层,注入Feign客户端接口,面向接口编程调用方...
  • Spring Cloud Gateway 调用Feign异步问题

    千次阅读 热门讨论 2021-04-19 15:27:20
    Spring Cloud Gateway 调用Feign异步报错问题#HttpMessageConverters#异步调用问题 #HttpMessageConverters #异步调用问题
  • Spring Cloud 为开发者提供了快速构建分布式系统中一些常见模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态)。分布式系统的协调...
  • 背景在第三方API对接中通常所有接口都需要在Header或Param放置固定参数(Token、开发者...这个时候就可以使用Feign的Interceptor功能。实现Talk is cheap,show me the code.下面选择一个具体场景,需要某个FeignClie...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,005
精华内容 4,802
关键字:

获取feign调用的路由