使用okhttp替换Feign默认Client的操作

一 关键pom

<dependencies>
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <!-- Spring Cloud OpenFeign的Starter的依赖 -->
 <dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>
 <dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
 </dependency>
</dependencies>

二 核心配置

server:
 port: 8011
spring:
 application:
 name: ch4-3-okhttp

feign:
 httpclient:
   enabled: false
 okhttp:
   enabled: true

三 其他代码位置

https://github.com/cakin24/spring-cloud-code/tree/master/ch4-3/ch4-3-okhttp

四 运行测试

补充:Feign - 独立使用 - 替代HttpClient

学习项目中,短连接Web服务器和长连接IM服务器之间,是相互配合的。在分布式集群的环境下,用户首先通过短连接登录Web服务器。Web服务器在完成用户的账号/密码验证,返回uid和token时,还需要通过一定策略,获取目标IM服务器的IP地址和端口号列表,返回给客户端。客户端开始连接IM服务器,连接成功后,发送鉴权请求,鉴权成功则授权的长连接正式建立。

短连接的调用,使用Feign 技术。下面是详解。

看完之后,Feign 独立使用,完全可以替换掉目前的Http 客户端调用方法。

​ 1.1. Feign短连接Restful调用

一般来说,短连接的服务接口,都是基于应用层Http协议的Http api 或者RESTful api实现,通过JSON文本格式返回数据。如何在Java服务端调用其他节点的Http api 或者RESTful api呢?

至少有以下几种方式:

(1)JDK原生的URLConnection

(2)Apache的Http Client/HttpComponents

(3)Netty的异步HTTP Client

(4)Spring的RestTemplate

目前用的最多的,基本上是第二种,这也是在单体服务时代,最为成熟和稳定的方式,也是效率较高的短连接方式。

插入一个解释: 什么是RESTful api。REST的全称是 Representational State Transfer,它是一种API接口的风格、也而不是标准,只是提供了一组调用的原则和约束条件。也就是说,在短连接服务的领域,它算是一种特殊格式的HTTP api。

回到前面的话题,如果同一个Http api/RESTful api 接口,倘若不止一个短连接服务器提供,而是有多个节点提供服务,那么,简单的使用Http Client调用,就无能为力了。

Http Client/HttpComponents调用不能根据接口的负载、或者其他的条件,去判断哪一个接口应该调用,哪一个接口不应该调用。解决这个问题的方式是啥呢?

可以使用Feign来调用多个服务器的同一个接口。Feign不仅仅可以进行同接口多服务器的负载均衡,一旦使用了Feign作为http api的客户端,调用远程的http接口就会变得像调用本地方法一样简单。

Feign是何方神圣?它是Netflix开发的一个声明式、模板化的HTTP客户端, Feign的目标是帮助Java工程师更快捷、优雅地调用HTTP API//RESTful api。另外,Feign被无缝集成到了SpringCloud微服务框架,使用Feign后,可以非常方便项目SpringCloud微服务技术。

如果项目使用了SpringCloud技术,那就就可以更加方便的声明式使用Feign。如果没有使用SpringCloud,使用Feign也非常之简单。Netflix Feign目前改名为OpenFeign,最新版本是2018.5发布的9.7.0。OpenFeign在Java应用中,负责处理与远程Web服务的请求响应,最大限度降低编码复杂性。可以说是Java应用中调用Web服务的客户端的利器。

下面就看看在单独使用Feign的场景下,是怎么调用远程的http服务。

引入Feign依赖的jar包到pom.xml:

 <dependency>
 <groupId>io.github.openfeign</groupId>
 <artifactId>feign-core</artifactId>
 <version>9.7.0</version>
</dependency>
<dependency>
 <groupId>io.github.openfeign</groupId>
 <artifactId>feign-gson</artifactId>
 <version>9.7.0</version>
</dependency>

接下来,就可以开始使用Feign来调用远程的Http API了。

1.1.1. 短连接API的接口准备

前面讲到,高并发的IM系统中,用户的登录与认证、好友的更新与获取等等一些低频的请求,这些都使用短连接来实现。

作为演示,这里仅仅列举两个短连接的API接口:

(1) http://localhost:8080/user/{userid}

这个接口的功能,是用户获取用户信息,是一个典型的RESTful类型的接口。{userid}是一个占位符,调用的时候,需要替换成用户id。 比如说如果用户id为1,调用的链接为:http://localhost:8080/user/1 。

(2) http://localhost:8080/login/{username}/{password}

这个接口的功能,用户登录的认证。占位符{username}是表示用户名称,占位符{password}表示用户密码。 比如说如果用户名称为zhangsan,密码为123调用的链接为:http://localhost:8080/login/zhangsan/123 。

上面的接口很简单,仅仅是为了演示,不能用于生产场景。这些API可以使用Spring MVC 等常见的WEB技术来实现。

1.1.2. 申明远程接口的本地代理

如何通过Feign技术,来调用上面的这些Http API呢?

第一步,需要创建一个本地的API的代理接口。具体如下:

package com.crazymakercircle.imServer.feignClient;
import feign.Param;
import feign.RequestLine;
public interface UserAction
{
 @RequestLine("GET /login/{username}/{password}")
 public String loginAction(
   @Param("username") String username,
   @Param("password") String password);
 @RequestLine("GET /user/{userid}")
 public String getById(
   @Param("userid") Integer userid);
}

在代理接口中,为每一个远程Http API定义一个方法。

如何将方法对应到远程接口呢?

在方法的前面,加上一个@RequestLine 注解,注明远程Http API的请求地址。这个地址不需要从域名和端口开始,只需要从URI的根目录“/”开始即可。

比如,如果远程Http API的URL为:http://localhost:8080/user/{userid} ,@RequestLine 声明的值,只需要配成 /user/{userid} 即可。

如何给接口传递参数值呢?

在方法的参数前面, 加上一个 @Param 注解即可。 @Param内容为HTTP链接中参数占位符的名称。绑定好之后,实际这个Java接口中的参数值,会替换到@Param注解中的占位符。

比如:由于getById的唯一参数 userid的 @Param注解中,用到的占位符是userid。那么,通过调用 userAction.getById(100) ,那么userid的值100,就会用来替换掉请求链接http://localhost:8080/user/{userid} 中占位符userid,最终得到的请求链接为:http://localhost:8080/user/100。

1.1.3. 远程API的本地调用

在完成远程API的本地代理接口的定以后,接下来的工作就是调用本地代理,这个工作也是非常的简单。

还是以疯狂创客圈的实战项目,获取用户信息、和用户登录两个API的代理接口的调用为例。

实战的代码如下:

import com.crazymakercircle.imServer.feignClient.UserAction;
import feign.Feign;
import feign.Request;
import feign.Retryer;
import feign.codec.StringDecoder;
import org.junit.Test;
/**
 * Created by 尼恩 at 疯狂创客圈
 */
//@ContextConfiguration(
//  locations = { "classpath:application.properties" })
//@RunWith(SpringJUnit4ClassRunner.class)
//@Configuration
//自动加载配置信息
//@EnableAutoConfiguration
public class LoginActionTest
{
/* // 服务器ip地址
 @Value("${server.web.user.url}")
 private String userBase;*/
 @Test
 public void testLogin()
 {
  UserAction action = Feign.builder()
//    .decoder(new GsonDecoder())
    .decoder(new StringDecoder())
    .options(new Request.Options(1000, 3500))
    .retryer(new Retryer.Default(5000, 5000, 3))
    .target(
      UserAction.class,
//      userBase
      "http://localhost:8080/"
    );
  String s = action.loginAction(
    "zhangsan",
    "zhangsan"
  );
  System.out.println("s = " + s);
 }
 @Test
 public void testGetById()
 {
  UserAction action = Feign.builder()
//    .decoder(new GsonDecoder())
    .decoder(new StringDecoder())
    .target(
      UserAction.class,
      "http://localhost:8080/"
    );
  String s = action.getById(2);
  System.out.println("s = " + s);
 }
}

主要的也是最为核心的就一步,构建一个远程代理接口的本地实例。使用Feign.builder() 构造器模式方法,带上一票配置方法的链式调用。主要的链式调用的配置方法介绍如下:

(1)target 配置方法

为构造器配置本地的代理接口,和远程的根目录。代理接口类的每一个接口方法前@RequestLine 声明的值,最终都会加上这个根目录。这个是最为重要的一个配置方法。代理接口类很重要,最终Feign.builder() 构造器返回的本地代理实例类型,就这个接口。

(2)options配置方法

options方法指定连接超时时长及响应超时时长。

(3)retryer配置方法

retryer方法主要是指定重试策略。

(4)decoder配置方法

decoder方法指定对象解码方式,这里用的是基于String字符串的解码方式。如果需要使用Jackson的解码方式,需要在pom.xml中添加Jackson的依赖。

主要的配置方法,就介绍这些,具体使用和其他的方法,请参见官网。

通过Feign.builder() 构造完成代理实例后,调用远程API,就变成了调用Java函数一样的简单。

建议,如果是独立调用Http服务,尽量使用Feign。

一是简单,

二是如果采用httpclient或其他相对较重的框架,对初学者来说编码量与学习曲线都会是一个挑战。

三是,既可以独立使用Feign,又可以方便后续的和Spring Could微服务框架继承。

总之,何乐而不为呢?

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • SpringCloud Open feign 使用okhttp 优化详解

    我就废话不多说了,大家还是直接看代码吧~ <!--web 模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!--排除tomcat依赖 --> <exclusion> <artifactId&

  • SpringBoot 配置 okhttp3的操作

    1. Maven 添加依赖 <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.10.0</version> </dependency> 2. application.properties 配置文件 ok.http.connect-timeout=30 ok.http.re

  • 基于Feign使用okhttp的填坑之旅

    1.由于项目需要远程调用http请求 因此就想到了Feign,因为真的非常的方便,只需要定义一个接口就行. 但是feign默认使用的JDK的URLHttpConnection,没有连接池效率不好,从Feign的自动配置类FeignAutoConfiguration中可以看到Feign除了默认的http客户端还支持okhttp和ApacheHttpClient,我这里选择了okhttp,它是有连接池的. 2.看看网络上大部分博客中是怎么使用okhttp的 1).引入feign和okhttp的mav

  • 使用okhttp替换Feign默认Client的操作

    一 关键pom <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Cloud OpenFeign的Starter的依赖 --> <dependency> &l

  • 解决Feign切换client到okhttp无法生效的坑(出现原因说明)

    提示:如果只看如何解决问题,请看文章的末尾如何解决这个问题 1. 场景描述 最近项目中使用了feign当做http请求工具来使用.相对于httpclient.resttemplate来说,fegin用起来方便很多. 然后项目有httptrace的需求,需要输出请求日志. 所以就开启了feign自己的日志,发现它自带的日志是debug级别才能打印.而且是逐行打印的,看日志非常的不方便.所以需要输出json格式的日志最好. 2.解决步骤 2.1 引入feign依赖 <dependency> <

  • SpringCloud Feign使用ApacheHttpClient代替默认client方式

    目录 使用ApacheHttpClient代替默认client ApacheHttpClient和默认实现的比较 ApacheHttpClient使用 apache的HttpClient的默认重试机制 maven 异常重试log RetryExec DefaultHttpRequestRetryHandler 使用ApacheHttpClient代替默认client ApacheHttpClient和默认实现的比较 Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP

  • SpringCloud Feign使用ApacheHttpClient代替默认client方式

    目录 使用ApacheHttpClient代替默认client ApacheHttpClient和默认实现的比较 ApacheHttpClient使用 apache的HttpClient默认重试机制 maven 异常重试log RetryExec DefaultHttpRequestRetryHandler 使用ApacheHttpClient代替默认client ApacheHttpClient和默认实现的比较 Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请

  • 完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题

    事发地 原默认的Feign是使用URLConnector进行通信的,当换为okhttp时,直接引入包及配置以下内容根本不生效,还是走原生的. feign: okhttp: enable: true 事件还原 创建项目并引入pom相关的依赖如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xml

  • SpringCloud使用Feign实现动态路由操作

    目录 一.理解及原理 1.1理解 1.2原理 二.Feign搭建实现步骤 三.配置文件(pom.xml) 三.程序代码 四.结果演示 一.理解及原理 1.1理解 Feign基于接口 + 注解的方式,一个http请求调用的轻量级框架 Feign是Netflix开发的声明式.模板化的HTTP客户端, Feign可以帮助我们更快捷.优雅地调用HTTP API. Feign是一种声明式.模板化的HTTP客户端(仅在Application Client中使用).声明式调用是指,就像调用本地方法一样调用远程

  • JS基于正则截取替换特定字符之间字符串操作示例

    本文实例讲述了JS基于正则截取替换特定字符之间字符串操作.分享给大家供大家参考,具体如下: 示例1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"&

  • 微信小程序图片加载失败时替换为默认图片的方法

    先看一下效果图: 1.第一种情况:单独加载一个图片 index.wxml代码: <image class="userinfo-avatar" src="{{avatar}}" binderror="errorFunction"></image> index.js代码: errorFunction: function(){ this.setData({ avatar: '/image/default.png' }) } 2.

  • pycharm 更改创建文件默认路径的操作

    1.操作 依次找到以下路径修改为自己想要的路径即可: PyCharm-->Settings-->Appearance&Behavior-->System Setting-->Project Opening-->Default directory 2.图示 以上这篇pycharm 更改创建文件默认路径的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • laravel框架select2多选插件初始化默认选中项操作示例

    本文实例讲述了laravel框架select2多选插件初始化默认选中项操作.分享给大家供大家参考,具体如下: 项目中有发送消息功能,需要能通过搜索,多选用户,来指定发送人.使用 select2 插件来完成. select2 的 html 代码如下: <div class="form-group" id="member_group"> <label class="col-lg-3 control-label required"&g

随机推荐