-
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 调用其他微服务接口时,url地址匹配错误
2021-01-20 11:49:24feign调用方法: @RequestMapping(value = /resources/ocircuit/textInfo, method = {RequestMethod.GET}, produces = text/plain;charset=utf-8) String getOcircuitTextRouteInfo(@PathVariable(name = resID) ... -
代码经验---feign调用实现url和接口路径的动态配置化
2021-04-21 21:45:49在微服务盛行的今天,做接口开发请求第三方服务的接口,大概率会用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可配置,请求路径也可实现可配置化,
如果有其它方式还请留言多交流; -
反射feign接口,调用feign的方法
2021-04-22 10:40:44主要是使用了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); } }
-
Spring Cloud + Feign实现微服务负载路由
2021-06-01 12:36:19项目的启动顺序为 ...微服务(提供服务):节点两个【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.javapackage 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 配置文件ymlserver: 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] -
Feign的自定义配置及使用
2020-04-09 23:09:29[转]http://c.biancheng.net/view/5362.html -
关于Feign调用报404的问题
2021-08-20 00:32:37关于Feign调用报404的问题 一、报错信息 主要报错信息 status 404 reading XxxFeignService#methodName(Params) 可以看到这个是远程服务未找到的问题,马上检查方法的调用路由以及被调用方路由,发现没错… 诶,我... -
SpringCloud配置服务注册中心实现Ribbon及Feign调用
2021-05-11 14:40:13本章主要来配置一下SpringCloud中的eureka(服务注册中心)以及服务之间分别使用Ribbon和Feign调用服务,在配置之前各位小伙伴可以看一下SpringBoot和SpringCloud版本对应关系,SpringBoot和SpringCloud之间的... -
聊聊如何根据环境动态指定feign调用服务名
2021-07-15 09:46:34前言 前段时间和朋友聊天,他说他部门老大给他提了一个需求,这个需求的背景是这样...消费方feign调用时,直接通过 @FeignClient(name = "user_dev") 来进行调用,因为他们是直接把feignClient的name直接写死在代码里 -
(springCloud-8 Zuul网关路由的基本配置feign实现接口调用)
2020-08-16 17:16:39Zuul的作用 统一将外部请求转发到具体的微服务实列上面,是...--路由网关 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、在这里使用... -
基于springcloud的灰度实现方案(三)-feign调用
2021-05-24 18:53:13首先,我们在feign调用时,使用了FeignClient注解。#接口调用 @FeignClient("demo-service") public interface DemoServiceFeginClient { } # 开启feign @EnableFeignClients(basePackages = {"com.yxkong -
【Java学习笔记(六十二)】之Feign,网关Gateway,路由,过滤器,配置中心,服务总线
2020-11-09 21:36:39之前使用Ribbon的负载均衡功能,简化了远程调用时的代码,但是每次调用都需要写基本相同的代码,代码重复性高。Feign可以把Rest的请求进行隐藏,伪装成类似Controller一样,我们不需要拼接url,这些工作都可以让... -
CGB2005 0928 SpringCloud05 order订单模块添加feign远程调用+rabbitMQ发布&路由模式
2020-09-28 19:42:19定义接口 即远程调用的功能(Feign继承的ribbon的RestTemplate远程调用) 接口的实现类(Feign继承的hystrix的回调 错误降级) ItemFeignServiceFB 获取商品列表的降级方法,模拟使用缓存数据 UserFei -
通过反射获取FeignClient并调用方法
2022-01-05 14:44:31一个外部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进行分布式服务调用
2019-10-08 15:05:18添加feign依赖 org.springframework.cloud spring-cloud-starter-openfeign 2.1.1.RELEASE 启动类上添加@EnableFeignClients注解 服务消费方创建Feign接口 这里是继承服务提供方提供出来的feign接口(pom文件... -
Feign远程调用组件 和 GateWay网关组件
2021-12-23 16:21:22Feign是Netflix开发的一个轻量级RESTful的HTTP服务客户端(用它来发起请求,远程调用的),是以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用,Feign被广泛应用在Spring Cloud... -
Feign调用connection refused,Caused by: java.net.ConnectException: Connection refused: connect
2020-10-16 15:42:39feign 调用 connection refused 解决问题: 请查看被调用的服务 uri 是否正确!!!正确配置后解决问题 -
rpc调用过程原理分析以及Dubbo、Feign调用过程
2021-03-10 16:59:19RPC是远程过程调用(Remote Procedure Call)的缩写形式。 RPC调用流程图 客户端方法:服务调用方所调用的接口 客户端代理:将接口封装成代理对象,并序列化请求参数、反序列化响应结果,使用远程传输协议调用... -
Spring Cloud系列_19 Hystrix feign实现服务监控
2021-05-16 14:50:59可以分别调用下两个项目的服务,可以看到监控信息的变化 访问http://localhost:9000/hystrix/ 可以看到之前的配置监控地址的界面,增加http://localhost:9000/turbine.stream配置后发现出现了可视化界面,显示了两... -
spring-cloud 原创代码例子包含服务发现、服务注册、服务路由、熔断器、feign等
2018-05-21 14:46:05spring-cloud 原创代码例子包含服务发现、服务注册、服务路由、熔断器、feign等 -
Feign接口内部调用进行权限校验
2021-06-28 09:40:49在目前微服务的体系下,我们服务url的访问有两种,一种是从网关(gateway,zuul)路由进来,还有一种就是通过feign接口内部调用,那么结合spring-security就存在以下几种场景: 1.外部请求从gateway访问,需要鉴权(任何CURD的... -
Feign【远程调用服务】和zuul【网关】的设计
2021-09-10 19:20:37远程调用 添加远程调用的依赖 yml配置文件内容 设计远程调用接口 业务层注入远程调用对象 启动类添加注解 重要注解 @EnableFeignClients注解 @FeignClient注解 zuul网关设计 添加网关设计依赖 启动类添加... -
springcloud-ribbon和feign的断路由
2019-04-10 21:00:24在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(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:20Spring Cloud Gateway 调用Feign异步报错问题#HttpMessageConverters#异步调用问题 #HttpMessageConverters #异步调用问题 -
SpringCloud之学习笔记(Feign+consul)
2021-08-31 18:18:24Spring Cloud 为开发者提供了快速构建分布式系统中一些常见模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态)。分布式系统的协调... -
Feign Interceptor 拦截器实现全局请求参数
2021-01-14 09:08:23背景在第三方API对接中通常所有接口都需要在Header或Param放置固定参数(Token、开发者...这个时候就可以使用Feign的Interceptor功能。实现Talk is cheap,show me the code.下面选择一个具体场景,需要某个FeignClie...