Netflix之第一个Ribbon程序(六)

Ribbon简介

Ribbon是一个在云服务中久经沙场的客户端IPC库,它提供以下的一些特性:

  1. 负载均衡
  2. 故障容错
  3. 在异步和动态的模型中支持多协议通讯(HTTP、TCP、UDP)
  4. 缓存与批处理

引入Ribbon依赖,可以去Ribbon的maven仓库获取,下面是一个maven引入示例:

<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon</artifactId>
    <version>2.2.2</version>
</dependency>

Ribbon所包含的模块

  1. ribbon:在其他Ribbon模块和Hystrix上集成负载均衡、容错、缓存/批处理的api
  2. ribbon-loadbalancer:可以独立或与其他模块一起使用的负载均衡器的api
  3. ribbon-eureka:使用Eureka客户端为云提供动态服务器列表的api
  4. ribbon-transport:使用带有负载均衡功能的RxNetty支持HTTP、TCP和UDP协议的传输客户端
  5. ribbon-httpclient:构建在Apache HttpClient之上,与负载均衡器集成的REST客户端
  6. ribbon-example:提供了一些示例
  7. ribbon-core:客户端配置api和其他共享api

我们将会使用蓝色字体标记的几个模块用作演示。

负载均衡器组件

Ribbon提供的基本功能

  1. 向通信客户端提供公共DNS名称或单个服务器的IP
  2. 根据特定的逻辑选择服务器

Ribbon提供的高级功能

  1. 通过将客户端划分为区域(如数据中心的机架),在相同区域中减少服务器延迟,从而在客户端和服务器之间建立关联
  2. 保持服务器的统计信息,避免出现高延迟或频繁故障的服务器
  3. 保持区域的统计信息,避免可能出现停机的区域

负载均衡器的三大子模块

  1. Rule:确定从列表返回哪个服务的逻辑组件
  2. Ping:在后台运行的组件以确保服务的活跃度
  3. ServerList:这可以是静态的或动态的。如果它是动态的(由DynamicServerListLoadBalancer使用),后台线程将在特定的时间间隔刷新和过滤列表

创建Ribbon程序

如架构图所示,Ribbon充当负载均衡器的作用,能够让我们的服务消费者调用到自己想使用的服务,服务消费者不用关心中间具体的操作,只需要将要调用的服务信息告诉负载均衡器,Ribbon就会从相应的服务集群中选择一个可以使用的服务器,供服务消费者调用。

我们创建两个简单maven项目,ribbon-server和ribbon-client,ribbon-server充当服务端,提供服务,并启动两个不同的服务实例(端口不同),ribbon-client充当客户端,发起服务调用。为了方便项目的搭建,我们这里使用Spring Boot(如果不清楚Spring Boot的同学,可以查看Spring Boot的简单使用(二),做一个大致了解)来快速开始,访问Spring Boot官网,获取最新的依赖,我这里使用的最新稳定版本是2.0.1,加入到我们ribbon-server项目的pom.xml中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>

在ribbon-server下新建com.init.springCloud包,创建启动类ServerApp,用控制台输入不同的端口来启动不同的项目,代码如下:

package com.init.springCloud;

import java.util.Scanner;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class ServerApp {

	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner scan = new Scanner(System.in);
		String port = scan.nextLine();
		new SpringApplicationBuilder(ServerApp.class).properties("server.port=" + port).run(args);
	}

}

再创建一个控制器类ServerController来返回当前服务的信息,这里我们让服务返回一个Person类的信息,两个类的代码如下:

package com.init.springCloud;

import lombok.Data;
//这里使用了lombok,不使用这个的同学可以去掉下面这个注解,然后手动添加getter、setter方法
@Data
public class Person {

	private Integer id;			//主键ID
	private String name;		//姓名
	private String info;		//信息,根据URL地址查看服务的来源
	
}
package com.init.springCloud;

import javax.servlet.http.HttpServletRequest;

import org.springframework.http.MediaType;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServerController {

	@RequestMapping(value = "/search/{id}", method = RequestMethod.GET, 
			produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public Person searchPerson(@PathVariable Integer id,HttpServletRequest request){
		Person person = new Person();
		person.setId(id);
		person.setName("Spirit");
		person.setInfo(request.getRequestURL().toString());
		return person;
	}
	
}

运行ServerApp类的main()方法,输入8082,启动第一个server服务;再次启动main()方法,输入8083,启动第二个server服务。

然后为ribbon-client项目引入Ribbon的依赖,进入Ribbon依赖仓库,引入Ribbon的核心包ribbon-core和http请求包ribbon-httpclient,版本的话,我这里引入的是最新稳定版本2.2.5

<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon-core</artifactId>
    <version>2.2.5</version>
</dependency>
<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon-httpclient</artifactId>
    <version>2.2.5</version>
</dependency>

然后同样在ribbon-client项目下创建com.init.springCloud包,新建RibbonTest类,参照Ribbon的GitHub文档,创建负载请求,代码如下:

package com.init.springCloud;

import com.netflix.client.ClientException;
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.niws.client.http.RestClient;

public class RibbonTest {

	public static void main(String[] args) {
		
		//设置要请求的服务器
		ConfigurationManager.getConfigInstance().setProperty(
	      		"sample-client.ribbon.listOfServers", 
	      		"localhost:8082,localhost:8083");
		//设置REST请求客户端
		RestClient client = (RestClient) ClientFactory.getNamedClient("sample-client");
		//创建请求实例
		HttpRequest request = HttpRequest.newBuilder().uri("/search/1").build();
		//连续发送10次请求到服务器
		for(int i=0; i<10; i++){
			try {
				HttpResponse response = client.executeWithLoadBalancer(request);
				String result = response.getEntity(String.class);
				System.out.println("请求结果:"+result);
			} catch (ClientException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	
}

笔者这里在引用Netflix提供的Ribbon快速开始文档的时候,出了些问题,由于文档比较久了,示例并不能直接使用,所以做了一些修改,同时,ribbon-httpclient是基于Apache的Http请求的,Ribbon弃用了这个方法,转而使用自己的内部http方法,时间关系,我在查阅文档的时候并没有找到这个替代的方法,就放弃了,如果有解决了这个问题的小伙伴,可以分享给我。

运行RibbonTest类的main()方法,我们可以看到测试类的方法是轮询请求了两个服务:

轮流去请求两个服务,是因为调用了Ribbon的Rule规则里面的RoundRobinRule,这是Ribbon的默认请求规则。Ribbon更加详细的信息后续再更。

源码点击这里

最后,大家有什么不懂的或者其他需要交流的内容,也可以进入我的QQ讨论群一起讨论:654331206

Spring Cloud系列:

Spring Cloud介绍与环境搭建(一)

Spring Boot的简单使用(二)

Spring Cloud服务管理框架Eureka简单示例(三)

Spring Cloud服务管理框架Eureka项目集群(四)

Spring Cloud之Eureka客户端健康检测(五)

Netflix之第一个Ribbon程序(六)

Ribbon负载均衡器详细介绍(七)

Spring Cloud中使用Ribbon(八)

具有负载均衡功能的RestTemplate底层原理(九)

OpenFeign之第一个Feign程序(十)

OpenFeign之feign使用简介(十一)

Spring Cloud中使用Feign(十二)

Netflix之第一个Hystrix程序(十三)

Netflix之Hystrix详细分析(十四)

Spring Cloud中使用Hystrix(十五)

Netflix之第一个Zuul程序(十六)

Spring Cloud集群中使用Zuul(十七)

Netflix之Zuul的进阶应用(十八)

消息驱动之背景概述(十九)

消息中间件之RabbitMQ入门讲解(二十)

消息中间件之Kafka入门讲解(二十一)

Spring Cloud整合RabbitMQ或Kafka消息驱动(二十二)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值