首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >非Spring环境下的Ribbon+Feign使用宝典

非Spring环境下的Ribbon+Feign使用宝典

作者头像
白石
发布2019-08-23 09:53:49
1.2K0
发布2019-08-23 09:53:49
举报
文章被收录于专栏:白石白石

Ribbon是一个负载均衡客户端,可以很好的控制http和tcp的一些行为,一般都是Ribbon搭配Feign一起使用;Feign默认集成了ribbon

添加feign的依赖

compile('io.github.openfeign:feign-core:9.5.0')    
compile('io.github.openfeign:feign-jackson:9.5.0')    
compile('io.github.openfeign:feign-ribbon:9.5.0')    

build.gradle文件内容:

apply plugin: 'java'
apply plugin: 'eclipse'

group = 'org.wjw.standardribbon'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = 1.8
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

repositories {
  mavenLocal()
  maven{ url "http://SVN:8081/nexus/content/groups/public"}
  mavenCentral()
  jcenter()
}


dependencies {
	compile('org.slf4j:slf4j-api')
	compile('org.slf4j:slf4j-log4j12:1.7.25')
	compile('commons-logging:commons-logging:1.2')
	
	compile('io.github.openfeign:feign-core:9.5.0')
	compile('io.github.openfeign:feign-jackson:9.5.0')
	compile('io.github.openfeign:feign-ribbon:9.5.0')
}

创建一个 Java Application 项目

执行: gradle init --type java-library

  • Feign声明式服务消费端接口 RemoteService接口中定义了一个名为getAdd的方法
package org.wjw.standardribbon.service;

import feign.Headers;
import feign.Param;
import feign.RequestLine;

public interface RemoteService {
	/**
	GET /add?a=1&b=2 HTTP/1.1
	Content-Type: application/json
	Accept: application/json
	User-Agent: Java/1.8.0_121
	Host: 192.168.2.113:8861
	Connection: keep-alive
	*/
	@Headers({ "Content-Type: application/json", "Accept: application/json" })
	@RequestLine("GET /add?a={a}&b={b}")
	int getAdd(@Param("a") int a, @Param("b") int b);
	
}
  • 编写ribbon.properties,该文件位于src/main/resources
#所有的key都以service-one开头,表明这些配置项作用于名为service-one的服务
service-one.ribbon.MaxAutoRetries=1
service-one.ribbon.MaxAutoRetriesNextServer=1
service-one.ribbon.OkToRetryOnAllOperations=true
service-one.ribbon.ServerListRefreshInterval=2000
service-one.ribbon.ConnectTimeout=3000
service-one.ribbon.ReadTimeout=3000
service-one.ribbon.listOfServers=192.168.2.113:8861,192.168.2.114:8861
service-one.ribbon.EnablePrimeConnections=false

config-server.ribbon.MaxAutoRetries=1
config-server.ribbon.MaxAutoRetriesNextServer=1
config-server.ribbon.OkToRetryOnAllOperations=true
config-server.ribbon.ServerListRefreshInterval=2000
config-server.ribbon.ConnectTimeout=3000
config-server.ribbon.ReadTimeout=3000
config-server.ribbon.listOfServers=192.168.2.114:7001
config-server.ribbon.EnablePrimeConnections=false

现在来看ribbon.properties中的配置项 所有的key都以service-one开头,表明这些配置项作用于名为service-one的服务.其实就是与之前绑定RemoteService接口的URL地址的schema相对应.

重点看ribbon.properties文件里的service-one.ribbon.listOfServers配置项,该配置项指定了服务生产端的真实地址. 与RemoteService接口绑定的URL地址是"http://service-one/",

在调用时会被替换为http://192.168.2.113:8861/http://192.168.2.114:8861/,再与接口中@RequestLine指定的地址进行拼接,得到最终请求地址. 本例中最终请求地址为http://192.168.2.113:8861/addhttp://192.168.2.114:8861/add

由于使用的ribbon,所以feign不再需要配置超时时长,重试策略.ribbon提供了更为完善的策略实现.

  • 本例中,服务端是一个简单的spring mvc,实现如下:
package org.wjw.cloud.service.controller;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ComputeController {
	private final Logger logger = Logger.getLogger(getClass());

	@Autowired
	private DiscoveryClient client;

	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public int add(@RequestParam int a, @RequestParam int b) {
		int r = a + b;

		ServiceInstance instance = client.getInstances(client.getServices().get(0)).get(0);
		logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
		return r;
	}

}

将服务生产端部署到Eureka中,在8861端口运行

  • Java启动APP
package org.wjw.standardribbon;

import org.wjw.standardribbon.model.User;
import org.wjw.standardribbon.service.PropService;
import org.wjw.standardribbon.service.RemoteService;

import com.netflix.client.ClientFactory;
import com.netflix.client.config.IClientConfig;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;

import feign.Feign;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.ribbon.LBClient;
import feign.ribbon.LBClientFactory;
import feign.ribbon.RibbonClient;

public class StdRibbon {
	public static void main(String[] args) throws Exception {
		ConfigurationManager.loadPropertiesFromResources("ribbon.properties");

		RibbonClient client = RibbonClient.builder().lbClientFactory(new LBClientFactory() {
			@Override
			public LBClient create(String clientName) {
				IClientConfig config = ClientFactory.getNamedConfig(clientName);
				ILoadBalancer lb = ClientFactory.getNamedLoadBalancer(clientName);
				ZoneAwareLoadBalancer zb = (ZoneAwareLoadBalancer) lb;
				zb.setRule(new RandomRule());
				return LBClient.create(lb, config);
			}
		}).build();

		/*
		  重点看ribbon.properties文件里的service-one.ribbon.listOfServers配置项,该配置项指定了服务生产端的真实地址.
                       与RemoteService接口绑定的URL地址是"http://service-one/",
                       在调用时会被替换为http://192.168.2.113:8861/或http://192.168.2.114:8861/,再与接口中@RequestLine指定的地址进行拼接,得到最终请求地址
                      本例中最终请求地址为"http://192.168.2.113:8861/add"或"http://192.168.2.114:8861/add"
		*/
		RemoteService service = Feign.builder().client(client).encoder(new JacksonEncoder())
				.decoder(new JacksonDecoder()).target(RemoteService.class, "http://service-one/");

		/**
		 * 调用测试
		 */
		for (int i = 1; i <= 10; i++) {
			int result = service.getAdd(1, 2);
			System.out.println("result:" + result);
		}

	}
}

首先利用com.netflix.config.ConfigurationManager读取配置文件ribbon.properties,该文件位于src/main/resources下. 重点在于通过RibbonClient.create()使得Feign对象获得了Ribbon的特性.之后通过encoder,decoder设置编码器与解码器,并通过target方法将之前定义的接口RemoteService与一个URL地址http://service-one/进行了绑定.

启动Spring Boot程序

执行: gradlew bootRun

默认端口号是:8080

在浏览器里测试

输入:http://127.0.0.1:8080/add?a=1&b=2

返回: 3

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 添加feign的依赖
  • 创建一个 Java Application 项目
  • 启动Spring Boot程序
  • 在浏览器里测试
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档