精华内容
下载资源
问答
  • fegin
    2021-03-15 09:16:27

    Fegin是一个声明式的HTTP调用框架。为什么是声明式的呢,其实在我们开发过程中一般都是声明一个接口,用@FeginClient标识,接口中的方法与调用方Controller保持一致,如参数,SpringMVC注解这样的。Fegin底层的调用方式是基于HTTP的,默认是使用JDK自带的通信框架,一般可以用HttpClient或OkHttp来进行替换Fegin底层的通信方式,引入pom,在yml文件开启即可。@FeginClient有很多参数,如url是指定服务的调用地址({url:https%3A//网页链接),value是服务在注册中心的名称,primary是指定该实现类的优先级,fegin是会自己生成代理类的,且primary默认是true的方式,这样是表明fegin自己生成的子类是优先级最高的,如果我们要自己写实现类,是会报错误的,所以primary是要做调整的。configuration是用来指定配置类的,fegin的配置类可以分为全局配置和局部配置,具备配置就是在@FeignClient参数中指定configuartion即可。Path属性是指定统一前缀的意思。Fegin可以轻而易举的集成ribbon和hystrix,ribbon是一个客户端的负载均衡工具,ribbon内部又集成了eureka注册中心,可以拿到注册中心服务的一些信息,从而进行一些负载算法对服务的调用。Fegin也支持请求压缩,请求数据过大时可以考虑对数据进行压缩,提高数据传输效率。Fegin也支持继承,开发方式controller和fegin接口都实现了同一个接口类,可以减少很多模板代码。fegin默认是不支持文件传输的,如果想要支持文件出传输,需要引入一些其他的依赖,fegin-from fegin-from-spring,并且为该fegin替换SpringFromEncoder编码器,才可以进行feign的文件传输。Fegin的底层其实就是基于动态代理+RestTemplate对我们声明的接口及方法,url+参数拼接,在返回数据的时候可以根据我们声明的返回类型去做转换,如果你的returnType指定为String,就会给你转成String,如果你指定其他实体,fegin也会帮你转换,但前提是合理的情况下,否则就会报错,当然你也可以直接用Fegin提供的Response来接收,然后自己做处理。

    更多相关内容
  • Springcloud fegin + oauth2 调用,实现token传递,解决fegin调用 ,无权限问题
  • 资源包含nacos seata 相应的软件和配置 ,包含了demo 工程,以及demo 使用的方式,操作手册 遇到的问题 是学习 研究seata 作为分布式组件好的工具
  • 该项目为springboot2.0+springcloud+eureka+fegin的分布式项目,使用fegin进行远程调用的简单demo,下载下来后直接导入到idea即可使用
  • fegin实现远程demo.zip

    2020-05-26 16:13:04
    用nacos做配置中心和服务注册中心,用fegin实现远程调用服务。 其中login是服务端,fegin是消费端。
  • *用于解决fegin无法传递授权信息 * @author wei_yunbo * @date 2018年5月30日 * @Copyright * * * =================Modify Record================= * Modifier date Content * wei_yunbo 2018...
  • 通过2个spring boot服务,实现consul的注册以及通过fegin(服务名)进行微服务直接的调用,实现HystrixCommand的容错处理
  • fegin动态调用

    2022-06-07 10:44:52
    fegin动态调用

    第一部分: apollo搭建 

    1>apollo下载

    链接:百度网盘 请输入提取码

    提取码:hvbo

    2>文件解压

    3>创建apollo数据库,sql文件在解压文件中的【sql】文件夹内;在任意一款mysql可视化工具中导入sql脚本,即可成功创建apollo需要使用的数据库

    4>配置库

    修改【demo】配置文件中的数据库连接,用户名/密码

    5 >启动

    cmd黑窗口下,进入【demo】所在的文件路径,执行 demo.sh start ;停止: demo.sh stop

    现象: 可以看到启动窗口,窗口在启动之后会自动关闭

    6>验证

    浏览器访问: http://localhost:8070/   用户名/密码为  apollo/admin

    7>创建一个项目

    第二部分:

    1>创建springboot项目

    2>pom文件引入jar

    <dependency>
    
        <groupId>com.ctrip.framework.apollo</groupId>
    
        <artifactId>apollo-client</artifactId>
    
        <version>1.3.0</version>
    
    </dependency>

    3>启动类添加注解 @EnableApolloConfig

    4>创建【server.properties】文件:

    文件路径:如果没有,需要自行新增

    内容为:

    env=DEV

    5>项目resources下创建【META-INF】文件夹,在【META-INF】下面在创建 app.properties

    内容:

    app.id= apollo上项目对应的appId

    6>项目resources下创建【apollo-env.properties】配置文件

    内容为

    local.meta=http://192.168.1.108:8080  -- 对应自己电脑ip
    
    dev.meta=http://192.168.1.108:8080    -- 对应自己电脑ip

    7>创建监听apollo配置文件,具体内容为

    package com.jia.customterfegin.config;
    
    import com.ctrip.framework.apollo.model.ConfigChangeEvent;
    import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
    import org.springframework.cloud.context.scope.refresh.RefreshScope;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    
    @Component
    @Slf4j
    public class RefreshApolloConfig implements ApplicationContextAware {
    
        private ApplicationContext applicationContext;
    
        @Autowired
        private RefreshScope refreshScope;
    
        @ApolloConfigChangeListener(value = {"application.properties"})
        public void onChange(ConfigChangeEvent changeEvent) {
            log.info("----------------------------修改了apollo配置-----------------------------");
            refreshTaskScheduleProperties(changeEvent);
        }
    
        private void refreshTaskScheduleProperties(ConfigChangeEvent changeEvent) {
            // 更新相应的bean的属性值,主要是存在@ConfigurationProperties注解的bean
            this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
            refreshScope.refreshAll();
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
    

    8>使用@value注解获取配置,为配置指定默认值 

     获取配置值需要是完整的url,包含但不限于:  http:ip:端口/请求地址/请求参数

    package com.jia.customterfegin.Server;
    
    import com.jia.customterfegin.Fegin.ServerFegin.ServerFeginClient;
    
    import lombok.extern.slf4j.Slf4j;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import org.springframework.beans.factory.annotation.Value;
    
    import org.springframework.stereotype.Service;
    
    import java.net.URI;
    
    @Service
    
    @Slf4j
    
    public class UserServer {
    
        @Autowired
    
        private ServerFeginClient serverFeginClient;
    
        @Value("${zjc.port:http://192.168.1.108:8087/ServerFegin}")
    
        private String port;
    
        @Value("${zjc.url:/user/1}")
    
        private String url;
    
        public String nameByServerFeginClient(Integer id) throws Exception {
    
            return serverFeginClient.resultNameById(new URI(port+url), id);
    
        }
    
    }

    9>fegin的接口中使用RequestMapping注解,其中注解属性value置为空

    package com.jia.customterfegin.Fegin.ServerFegin;
    
    import org.springframework.cloud.openfeign.FeignClient;
    
    import org.springframework.web.bind.annotation.PathVariable;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import org.springframework.web.bind.annotation.RequestParam;
    
    import java.net.URI;
    
    @FeignClient(name = "ServerFegin", url = "${zjc.port}", fallback = ServerFeginClientFallBack.class)
    
    public interface ServerFeginClient {
    
        @RequestMapping(value = "", method = RequestMethod.GET)
    
        public String resultNameById(URI uri, @RequestParam(value = "id") Integer id) throws Exception;
    
    }

    10>测试通过在apollo上面修改配置,观察调用地址是否变更

    展开全文
  • 用过Spring Cloud的朋友都知道用 fegin 很香,甚至后来者居上的Spring Cloud Alibaba,仍然整合 fegin 作为服务调用组件。 但是很多项目用不到微服务的,就是普通的单体应用,如何使用呢… feign 说明 fegin发展简介...

    问题:

    用过Spring Cloud的朋友都知道用 fegin 很香,甚至后来者居上的Spring Cloud Alibaba,仍然整合 fegin 作为服务调用组件。
    但是很多项目用不到微服务的,就是普通的单体应用,如何使用呢…

    feign 说明

    fegin发展简介

    com.netflix.feign 从2016 年后闭源,由 io.github.openfeign 来维护。
    在这里插入图片描述

    feign是什么呢,

    fegin其实就是一个http客户端调度框架。
    底层 fegin默认情况下,使用的jdk 原生的 UrlConnections 发送 http请求,没有连接池,所以一般使用fegin的时候,对采用 HttpClient 或者 Okhttp 作为fegin 的客户端进行使用。

    使用说明

    参考官网:https://github.com/OpenFeign/feign

    引入依赖

    注:我这里没有引入 feign-core,而是直接引入 feign-jackson

            <!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-jackson -->
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-jackson</artifactId>
                <version>11.2</version>
            </dependency>
    
    
            <!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp -->
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-okhttp</artifactId>
                <version>11.2</version>
            </dependency>
    
    

    创建 FeignClientFactory

    这里只是简单配置测试使用,可进一步进行自定义封装。

    public abstract class FeignClientFactory {
        /**
         * 创建 feign 客户端
         *
         * @param clazz class
         * @param url   url
         * @param <T>   泛型参数
         * @return T
         */
        public static <T> T create(Class<T> clazz, String url) {
            // 1、定义 okHttpClient
            okhttp3.OkHttpClient okHttpClient = new okhttp3.OkHttpClient()
                    .newBuilder()
                    .connectionPool(new ConnectionPool(5, 5L, TimeUnit.MINUTES))
                    .connectTimeout(15, TimeUnit.SECONDS)
                    .writeTimeout(20, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .build();
                    
            // 2、定义 feign 对应 OkHttpClient
            OkHttpClient client = new OkHttpClient(okHttpClient);
    
            // 3、创建 feign
            return Feign.builder()
                    .client(client)
                    .retryer(Retryer.NEVER_RETRY) // 重试机制
                    .encoder(new FeignEncoder())  // 自定义:入参编码器
                    .decoder(new StringDecoder()) // 定义:出参解码器
                    .decode404() // 解码404,方便测试
                    .target(clazz, url);
        }
    }
    
    

    配置自定义 encoder

    为什么配置这个呢,可参考:https://cloud.tencent.com/developer/article/1588499
    具体就是:
    当方法参数没有标注@Param注解时,编码器会起作用。
    eg:
    如果方法参数并没有被模版使用,那么他会被收集放到一个Map里,然后交给Encoder处理。因为默认的 Encoder 是 StringDecoder,无法解析map就会报错了。
    在这里插入图片描述

    public class FeignEncoder implements Encoder {
    
        @Override
        public void encode(Object object, Type bodyType, RequestTemplate template) {
            if (object != null) {
                String jsonString = JSON.toJSONString(object);
                template.body(jsonString.getBytes(), StandardCharsets.UTF_8);
            }
        }
    }
    

    使用场景

    这里我这里列举五种场景,基本可满足项目中用到场景。

    1、表单传参 – 普通参数

    1.1、定义api接口

    public interface TestOpenFeignApi {
    
        /**
         * 表单传参 * V1
         * 参数必须要加 @Param注解,否则会报错,
         * 注意这里的 @Param 要区别于MyBatis @Param 注解
         *
         * @param id   id
         * @param code code
         */
        @RequestLine("POST openFeignApi/findByIdAndCode?id={id_}&code={code_}")
        String findByIdAndCode(@Param("id_") Integer id, @Param("code_") String code);
        }
    

    1.2、对应SpringMvc接口

    @RestController
    @RequestMapping(value = "openFeignApi/")
    public class OpenFeignController {
    
    
        /**
         * 表单传参------测试普通表单传参
         *
         * @param id   id
         * @param code code
         */
        @PostMapping("/findByIdAndCode")
        public Map findByIdAndCode(@RequestParam(required = false) Integer id, @RequestParam(required = false) String code) {
            HashMap<String, Object> hashMap = Maps.newHashMap();
            hashMap.put("id", id);
            hashMap.put("code", code);
            return hashMap;
        }
        }
    

    1.3、Fegin调用

    @SpringBootTest
    public class OpenFeignTest {
    
    
        public static final String URL = "http://localhost:8080/";
    
        /**
         * 表单传参 -- 普通参数
         */
        @Test
        public void findById() {
            String str = FeignClientFactory.create(TestOpenFeignApi.class, URL).findByIdAndCode(1, "ali");
            System.out.println(str);
        }
        }
    

    2、表单传参 – pojo

    2.1、定义api接口

    @QueryMap 作用等同于多个 @Param

        /**
         * 表单传参 (pojo) * V2
         * 负责将对象编码为Map查询参数名到值的映射。
         *
         * @param city pojo
         */
        @RequestLine("GET openFeignApi/findByCity")
        String findByCity(@QueryMap City city);
    

    2.2、对应SpringMvc接口

        /**
         * 表单传参------测试pojo表单传参,注意这里不能带 @RequestParam 注解
         *
         * @param city city
         */
        @GetMapping("/findByCity")
        public String findByCity(City city) {
            System.out.println(city);
            return JSON.toJSONString(city);
        }
    

    2.3、Fegin调用

        /**
         * 表单传参 -- pojo
         */
        @Test
        public void findByCity() {
            String str = FeignClientFactory.create(TestOpenFeignApi.class, URL)
                    .findByCity(City.builder().cityCode(1001).cityName("杭州").build());
            System.out.println(str);
        }
    

    3、表单传参 – map

    3.1、定义api接口

        /**
         * 表单传参 (map) * V3
         * 负责将对象编码为Map查询参数名到值的映射。
         *
         * @param map map
         */
        @RequestLine("GET openFeignApi/findByMap")
        String findByMap(@QueryMap Map map);
    

    3.2、对应SpringMvc接口

        /**
         * 表单传参------测试 map表单传参,注意这里一定要带 @RequestParam 注解,否则无效
         *
         * @param map map
         */
        @GetMapping("/findByMap")
        public Map findByMap(@RequestParam Map map) {
            System.out.println(map);
            return map;
    
        }
    

    3.3、Fegin调用

        /**
         * 表单传参 -- map
         */
        @Test
        public void findByMap() {
            HashMap<Object, Object> map = Maps.newHashMap();
            map.put("cityCode", 1002);
            map.put("cityName", "上海");
            String str = FeignClientFactory.create(TestOpenFeignApi.class, URL)
                    .findByMap(map);
            System.out.println(str);
        }
    

    4、json传参 (带 header)

    4.1、定义api接口

        /**
         * json 传参 (& header传参) * V2
         *
         * @param city (json格式)
         */
        @RequestLine("POST /openFeignApi/findByJson")
        @Headers({"Content-Type: application/json","Accept: application/json"})
        String findByJsonAndHeader(@HeaderMap Map<String, String> headerMap, City city) ;
    
    

    4.2、对应SpringMvc接口

        /**
         * json传参
         *
         * @param city city
         */
        @PostMapping("/findByJson")
        public String findByJson(@RequestBody City city, HttpServletRequest request) {
            System.out.println(city);
            System.out.println(request.getHeader("token"));
            return JSON.toJSONString(city);
    
        }
    

    4.3、Fegin调用

        /**
         * json传参(带 header) -- pojo
         */
        @Test
        public void findByJsonAndHeader() {
            Map<String, String> headerMap = Maps.newHashMap();
            headerMap.put("token", "123");
            headerMap.put("cookie", "456");
            City city = City.builder().cityCode(1001).cityName("杭州").build();
    
            String str = FeignClientFactory.create(TestOpenFeignApi.class, URL)
                    .findByJsonAndHeader(headerMap, city);
    
            System.out.println(str);
        }
    

    5、调用接口返回POJO对象(常用)

    什么意思呢,就是调一个接口可以转换对应的 DTO,不用把返回接口的json字符串通过json解析工具解析为对象进行使用。

    5.1 重定义 FeignClientFactory decoder

        public static <T> T create2(Class<T> clazz, String url) {
            return Feign.builder()
                    .encoder(new FeignEncoder())
                    // 使用JacksonDecoder做解码
                    .decoder(new JacksonDecoder())
                    .decode404()
                    .target(clazz, url);
        }
    

    5.2 定义api接口

    这个接口是微信官方的,可以通过appid和secret及grantType直接调用获取token

    public interface WechatSdkApi {
        @RequestLine("GET /cgi-bin/token?appid={appid}&secret={secret}&grant_type={grant_type}")
        WxToken getToken(@Param("appid") String appid,
                         @Param("secret") String secret,
                         @Param("grant_type") String grantType);
    }
    

    5.3 Fegin调用

    @SpringBootTest
    public class WeChatApi {
        @Autowired
        private SiteConfig siteConfig;
    
        /**
         * 根据 appid 和 secret 及 client_credential  获取 token
         */
        @Test
        public void getToken() {
            WechatSdkApi sdkApi = FeignClientFactory.create2(WechatSdkApi.class, ApiConstants.WECHAT_GET_OPENID);
            WxToken apiToken = sdkApi.getToken(siteConfig.getAppId(), siteConfig.getSecret(), siteConfig.getGrantType2());
            System.out.println(apiToken.getAccessToken());
    
        }
    }
    

    5.2 Fegin调用

    在这里插入图片描述

    展开全文
  • 上一篇介绍了通过RestTemplate实现微服务之间请求调用,本篇介绍通过fegin的方式如何在微服务之间发送请求。

    目录

    一、前言

    1、关于Fegin

    2、注意事项

    3、POM依赖

    二、编码实现

    1、启动类

    2、创建openfeign接口

    3、Controller代码

    4、回调工厂

    三、文件配置

    1、Feign接口日志级别

    2、超时时间

    四、性能优化


    一、前言

    上一篇介绍了通过RestTemplate实现微服务之间请求调用,本篇介绍通过fegin的方式如何在微服务之间发送请求。

    1、关于Fegin

    1、Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端。

    2、Fegin内置Ribbon用来做客户端负载均衡。
    3、使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务
    4、Spring Cloud 在Feign的基础上支持了Spring MVC的注解,也就是OpenFeign。

    2、注意事项

    1、OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口。
    2、@RequesMapping不能在类名上与@FeignClient同时使用。

    3、POM依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!-- 熔断降级 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

    二、编码实现

    1、启动类

    启动类上要加 @EnableFeignClients

    /**
     * @ClassName: MsgApplication
     * @Description msg启动类
     * @author 月夜烛峰
     * @date 2022/7/22 08:53
     */
    @EnableFeignClients
    @EnableDiscoveryClient
    @SpringBootApplication
    public class MsgApplication {
        public static void main(String[] args) {
            SpringApplication.run(MsgApplication.class, args);
        }
    }
    

    否则定义的fegin接口不能自动装配,也即是不会被spring接管,报错信息如下:

    2、创建openfeign接口

    package com.zhufeng.web.api;
    
    import com.alibaba.fastjson.JSONObject;
    import com.zhufeng.web.fallback.UserFallbackFactory;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /**
     * @ClassName: FeignUserApi
     * @Description 对外提供api接口
     * @author 月夜烛峰
     * @date 2022/8/31 16:55
     */
    @FeignClient(value = "zhufeng-web-user", fallbackFactory = UserFallbackFactory.class)
    public interface ShowUserApi {
    
        /**
         * 根据id获取user信息
         * @param id
         * @return
         */
        @GetMapping("/fegin/{id}")
        JSONObject showUserById(@PathVariable("id") int id);
    
    }
    

    @FeignClient中,value配置为要访问的微服务名称,fallbackFactory为回调工厂。

    3、Controller代码

    package com.zhufeng.web.controller;
    
    import com.alibaba.fastjson.JSONObject;
    import com.zhufeng.web.api.ShowUserApi;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    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.RestController;
    
    /**
     * @ClassName: RestUserController
     * @Description TODO
     * @author 月夜烛峰
     * @date 2022/8/30 09:55
     */
    @Slf4j
    @RestController
    public class RestUserController {
    
        @Autowired
        ShowUserApi showUserApi;
    
        @RequestMapping("/fegin/{id}")
        public JSONObject showUserInfo(@PathVariable("id") int id) {
            log.info("接收到feign请求,id:"+id);
            JSONObject userJson = new JSONObject();
            userJson.put("status", "success");
            userJson.put("name","zhufeng");
            return userJson;
        }
    
        @RequestMapping("/user/{id}")
        public JSONObject showUserById(@PathVariable("id") int id) {
            log.info("请求参数id:"+id);
            return showUserApi.showUserById(id);
        }
    
    }
    

    4、回调工厂

    当访问异常时,回调工厂对返回进行进行特殊处理。

    package com.zhufeng.web.fallback;
    
    import com.alibaba.fastjson.JSONObject;
    import com.zhufeng.web.api.ShowUserApi;
    import feign.hystrix.FallbackFactory;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    /**
     * @ClassName: UserFallbackFactory
     * @Description fegin接口回调工厂类
     * @author 月夜烛峰
     * @date 2022/8/31 16:58
     */
    @Slf4j
    @Component
    public class UserFallbackFactory implements FallbackFactory<ShowUserApi> {
        @Override
        public ShowUserApi create(Throwable throwable) {
            log.error("请求接口报错。。。");
            return new ShowUserApi() {
                @Override
                public JSONObject showUserById(int id) {
                    log.info("调用工厂:id="+id);
                    JSONObject json = new JSONObject();
                    json.put("id", id);
                    json.put("status", "error");
                    json.put("type", "factory");
                    json.put("msg", "no user found...");
                    return json;
                }
            };
        }
    }
    
    

    在浏览器中 127.0.0.1:8081/user/1001 访问showUserById方法,该方法调用feign接口访问showUserInfo。

    可以正常获取数据,接口访问正常。

    注意:

    注册中心使用的nacos,需要将zhufengweb-user服务注册到nacos中。

    过程参考:《从0到1学SpringCloud——05 注册微服务到nacos

    三、文件配置

    1、Feign接口日志级别

    在Feign中内置了日志级别:

    NONE:默认值,不记录任何日志
    BASIC:仅记录请求方法、URL、响应状态码以及执行时间
    HEADERS:记录 BASIC 级别的基础上,记录请求和响应的 header
    FULL:记录请求和响应的 header、body 和元数据

    FULL虽然记录信息较全,但实际使用时因资源存储限制,大多使用BASIC。

    这里以FULL级别展示有哪些信息

    配置项:

    #feign接口信息打印
    logging.level.com.zhufeng.web.api.ShowUserApi=debug
    #全局配置
    feign.client.config.default.loggerLevel = full
    #也可指定微服务中打印feign信息
    #feign.client.config.zhufeng-web-user.loggerLevel=full

    运行效果,控制台打印了 ShowUserApi#showUserById 信息:

    2022-09-02 11:07:03.811  INFO 18022 --- [nio-8081-exec-2] c.z.web.controller.RestUserController    : 接收到feign请求,id:1001
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] <--- HTTP/1.1 200 (102ms)
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] connection: keep-alive
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] content-type: application/json
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] date: Fri, 02 Sep 2022 03:07:03 GMT
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] keep-alive: timeout=60
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] transfer-encoding: chunked
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] 
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] {"name":"zhufeng","status":"success"}
    2022-09-02 11:07:03.838 DEBUG 18022 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] <--- END HTTP (37-byte body)
    2022-09-02 11:07:04.797  INFO 18022 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: zhufeng-web-user.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    

    2、超时时间

    微服务请求通信中,极有可能出现请求超时或着网络不同的情况

    # 开启Feign对Hystrix的支持,使回调函数生效
    feign.hystrix.enabled=true
    
    # 超时时间可根据不同微服务进行配置,例如仅配置 zhufeng-web-user
    # 指定Feign连接提供者的超时时限,5秒
    feign.client.config.zhufeng-web-user.connectTimeout=5000
    # 指定Feign从请求响应的超时时限,5秒
    feign.client.config.zhufeng-web-user.readTimeout=5000
    
    #超时时间全局配置,全局配置只需要指定default即可
    #feign.client.config.default.loggerLevel = full
    # 指定Feign连接提供者的超时时限,5秒
    #feign.client.config.default.connectTimeout=5000
    # 指定Feign从请求响应的超时时限,5秒
    #feign.client.config.default.readTimeout=5000
    
    

    配置超时时间后,为验证是否生效,可在请求的接口中设置等待时间大于5秒

    对Controller代码进行修改,增加等待时间:

    @RequestMapping("/fegin/{id}")
    public JSONObject showUserInfo(@PathVariable("id") int id) {
        log.info("接收到feign请求,id:"+id);
        JSONObject userJson = new JSONObject();
        userJson.put("status", "success");
        userJson.put("name","zhufeng");
        try {
            for(int i=9;i>0;i--){
                log.info("请求等待中..."+i);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            log.error("服务超时,",e);
        }
        return userJson;
    }

    因为5秒内,没有返回数据,服务超时,返回信息为回调工厂UserFallbackFactory中配置的信息。 

    控制台日志信息:

    2022-09-02 10:49:47.964  INFO 17734 --- [nio-8081-exec-2] c.z.web.controller.RestUserController    : 接收到feign请求,id:1001
    2022-09-02 10:49:47.988  INFO 17734 --- [nio-8081-exec-2] c.z.web.controller.RestUserController    : 请求等待中...9
    2022-09-02 10:49:48.885 ERROR 17734 --- [ HystrixTimer-1] c.z.web.fallback.UserFallbackFactory     : 请求接口报错。。。
    2022-09-02 10:49:48.889  INFO 17734 --- [ HystrixTimer-1] c.z.web.fallback.UserFallbackFactory     : 调用工厂:id=1001
    2022-09-02 10:49:48.949  INFO 17734 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: zhufeng-web-user.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    2022-09-02 10:49:48.994  INFO 17734 --- [nio-8081-exec-2] c.z.web.controller.RestUserController    : 请求等待中...8
    2022-09-02 10:49:49.999  INFO 17734 --- [nio-8081-exec-2] c.z.web.controller.RestUserController    : 请求等待中...7
    2022-09-02 10:49:51.006  INFO 17734 --- [nio-8081-exec-2] c.z.web.controller.RestUserController    : 请求等待中...6
    2022-09-02 10:49:52.011  INFO 17734 --- [nio-8081-exec-2] c.z.web.controller.RestUserController    : 请求等待中...5
    2022-09-02 10:49:52.972 DEBUG 17734 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] <--- ERROR SocketTimeoutException: Read timed out (5098ms)
    2022-09-02 10:49:52.973 DEBUG 17734 --- [feng-web-user-1] com.zhufeng.web.api.ShowUserApi          : [ShowUserApi#showUserById] java.net.SocketTimeoutException: Read timed out
    	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:280)
    	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:306)
    	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:347)

    四、性能优化

    默认情况下Feign不使用线程池,在并发请求较多时,会产生性能问题,可做如下配置:

    # 使用httpclient链接池
    feign.httpclient.enabled=true
    # 连接池中最大连接数,默认值200
    feign.httpclient.max-connections=200
    # 每个route最大并发连接数 默认值50
    feign.httpclient.max-connections-per-route=50

    重新启动项目,日志级别设置为debug,控制台打印信息:

    2022-09-02 12:14:41.895 DEBUG 18667 --- [feng-web-user-1] o.a.h.client.protocol.RequestAuthCache   : Auth cache not set in the context
    2022-09-02 12:14:41.896 DEBUG 18667 --- [feng-web-user-1] h.i.c.PoolingHttpClientConnectionManager : Connection request: [route: {}->http://10.211.55.2:8081][total available: 0; route allocated: 0 of 50; total allocated: 0 of 200]
    2022-09-02 12:14:41.898 DEBUG 18667 --- [feng-web-user-1] h.i.c.PoolingHttpClientConnectionManager : Connection leased: [id: 0][route: {}->http://10.211.55.2:8081][total available: 0; route allocated: 1 of 50; total allocated: 1 of 200]
    2022-09-02 12:14:41.898 DEBUG 18667 --- [feng-web-user-1] o.a.http.impl.execchain.MainClientExec   : Opening connection {}->http://10.211.55.2:8081

    如果打印 PoolingHttpClientConnectionManager 相关信息,则说明配置已生效

    展开全文
  • Fegin的基本调用

    千次阅读 2022-01-05 14:13:55
    不需要fegin其他项目的接口显示出来 解决方案 添加FeignConfiguration类,重新启动 FeignConfiguration .java package com.seasky.middlegroundadmin.config; import feign.Feign; import org.springframework.boot....
  • Ribbon fegin自定义路由规则,公司本地环境共用一个注册中心路由到本地服务,直接把该类放到项目中即可,不用任何配置
  • 问题遇到的现象和发生背景 问题相关代码,请勿粘贴截图 通过fegin请求的controller package com.example.controller; import com.example.pojo.Ticket; import com.example.service.TicketService; import org....
  • 证明配置成功了,这两个微服务也可以互相调用了 四、微服务之间调用 第一步:添加远程调用依赖 使用Fegin实现远程调用,添加依赖,在父工程的时候我们已经添加了 就是这个: org.springframework.cloud spring-cloud-...
  • nacos fegin 整合异常

    2021-09-09 18:48:31
    nacos 整合 fegin 异常 版本环境: spring boot 2.5.4 spring cloud 2020.0.3 com.alibaba.cloud 2.2.0.RELEASE 代码内容 Fegin service 定义 @FeignClient(name="cloud-provider") public interface EchoService { ...
  • fegin需要实现类_Fegin

    2020-11-22 23:05:41
    Fegin客户端什么是Fegin,Fegin是一个声明式的Http客户端,它使得写Http客户端变得更简单,使用Fegin只需要创建一个接口并注解,它具有可插拔的注解特性,Nacos很好的兼容了Fegin,默认实现了负载均衡的效果,底层使用了...
  • Fegin使用——基本方式 @FeignClient(value = "XdocConsumer") public interface XdocConsumer { } /* 传单个文件 */ @PostMapping(value = "/xdoc/upLoadFile/{employeeId}",produces = {MediaType.APPLICATION_...
  • 2.1.Feign替代RestTemplate Fegin的使用步骤如下: 1引入依赖 我们在order-service服务的pom文件中引入feign的依赖: org.springframework.cloud spring-cloud-starter-openfeign 2添加注解 在order-service的启动...
  • 通过上篇文章分析我们知道,fegin客户端在初始化的时候,会通过jdk动态代理未为每个feignClient生成一个代理类,jdk动态代理主要是通过InvocationHandler接口的实现代理的增强.我们来看看生成代理时InvocationHandler...
  • fegin定义 fegin使用流程 引入fegin相关的依赖
  • fegin接口下载文件

    2022-05-13 10:02:58
    服务提供端这里结合的是minio文件服务器: controller,这里一定是void,不要指定返回内容 @RequestMapping("/file") @RestController public class FileSystemController { @Autowired private FileSystem...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,927
精华内容 3,970
关键字:

fegin

友情链接: ram_test.zip