SpringCloud-Ribbon[入门案例]
閱讀本文約花費: 4 (分鐘)
一、 Ribbon 在微服务中的作用
1 什么是 Ribbon
Ribbon 是一个基于 Http 和 TCP 的客服端负载均衡工具,它是基于 Netflix Ribbon 实现的。
它不像 spring cloud 服务注册中心、配置中心、API 网关那样独立部署,但是它几乎存在于每个 spring cloud 微服务中。包括 feign 提供的声明式服务调用也是基于该 Ribbon实现的。
ribbon 默认提供很多种负载均衡算法,例如 轮询、随机 等等。甚至包含自定义的负载均衡算法。
2 Ribbon 解决了什么问题
他解决并提供了微服务的负载均衡的问题。
二、 集中式与进程内负载均衡的区别
1 负载均衡解决方案的分类
目前业界主流的负载均衡方案可分成两类:
第一类:集中式负载均衡, 即在 consumer 和 provider 之间使用独立的负载均衡设施(可以是硬件,如 F5, 也可以是软件,如 nginx), 由该设施负责把 访问请求 通过某种策略转发至 provider;
第二类:进程内负载均衡,将负载均衡逻辑集成到 consumer,consumer 从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的 provider。Ribbon 就属于后者,它只是一个类库,集成于 consumer 进程,consumer 通过它来获取到 provider 的地址。
2 两种负载均衡方式结构图
三、 Ribbon 的入门案例
Ribbon 中对于集群的服务采用的负载均衡的策略默认的是轮询,本案例的项目结构
1.provider
1.1将 provider 打包。部署到 linux 环境中
1.2创建启动脚本 server.sh
注意修改 JAR_NAME
#!/bin/bash cd `dirname $0` CUR_SHELL_DIR=`pwd` CUR_SHELL_NAME=`basename ${BASH_SOURCE}` JAR_NAME=”springcloud-eureka-ribbon-provider-0.0.1-SNAPSHOT.jar” JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME #JAVA_MEM_OPTS=” -server -Xms1024m -Xmx1024m -XX:PermSize=128m” JAVA_MEM_OPTS=”” #SPRING_PROFILES_ACTIV=”-Dspring.profiles.active=配置文件变量名称” SPRING_PROFILES_ACTIV=”” LOG_DIR=$CUR_SHELL_DIR/logs LOG_PATH=$LOG_DIR/${JAR_NAME%..log echo_help() { echo -e “syntax: sh $CUR_SHELL_NAME start|stop” } if [ -z $1 ];then echo_help exit 1 fi if [ ! -d “$LOG_DIR” ];then mkdir “$LOG_DIR” fi if [ ! -f “$LOG_PATH” ];then touch “$LOG_DIR” fi if [ “$1” == “start” ];then # check server PIDS=`ps –no-heading -C java -f –width 1000 | grep $JAR_NAME | awk ‘{print $2}’` if [ -n “$PIDS” ]; then echo -e “ERROR: The $JAR_NAME already started and the PID is ${PIDS}.” exit 1 fi echo “Starting the $JAR_NAME…” # start nohup java $JAVA_MEM_OPTS -jar $SPRING_PROFILES_ACTIV $JAR_PATH >> $LOG_PATH 2>&1 & COUNT=0 while [ $COUNT -lt 1 ]; do sleep 1 COUNT=`ps –no-heading -C java -f –width 1000 | grep “$JAR_NAME” | awk ‘{print $2}’ | wc -l` if [ $COUNT -gt 0 ]; then break fi done PIDS=`ps –no-heading -C java -f –width 1000 | grep “$JAR_NAME” | awk ‘{print $2}’` echo “${JAR_NAME} Started and the PID is ${PIDS}.” echo “You can check the log file in ${LOG_PATH} for details.” elif [ “$1” == “stop” ];then PIDS=`ps –no-heading -C java -f –width 1000 | grep $JAR_NAME | awk ‘{print $2}’` if [ -z “$PIDS” ]; then echo “ERROR:The $JAR_NAME does not started!” exit 1 fi echo -e “Stopping the $JAR_NAME…” for PID in $PIDS; do kill $PID > /dev/null 2>&1 done COUNT=0 while [ $COUNT -lt 1 ]; do sleep 1 COUNT=1 for PID in $PIDS ; do PID_EXIST=`ps –no-heading -p $PID` if [ -n “$PID_EXIST” ]; then COUNT=0 break fi done done echo -e “${JAR_NAME} Stopped and the PID is ${PIDS}.” else echo_help exit 1 fi |
授权
chmod 755 service.sh |
然后通过脚本启动服务。
./service start |
2.consumer
消费者主要是注意service中的服务调用,代码如下
/** * @program: springcloud-eureka-consumer * @description: 用户的业务处理 * @author: 波波烤鸭 * @create: 2019-05-28 17:43 */ @Service public class UserService { /** * ribbon 负载均衡 * LoadBalancerClient 通过服务名称可以获取对应的服务的相关信息 ip port等 */ @Autowired private LoadBalancerClient loadBalancerClient; public List<User> getUsers(){ // ServiceInstance 封装的有服务的基本信息 IP和端口等 ServiceInstance si = this.loadBalancerClient.choose(“eureka-ribbon-provider”); StringBuilder sb = new StringBuilder(); sb.append(“http://”) .append(si.getHost()) .append(“:”) .append(si.getPort()) .append(“/user”); System.out.println(“服务地址:”+sb.toString()); // SpringMVC RestTemplate RestTemplate rt = new RestTemplate(); ParameterizedTypeReference<List<User>> type = new ParameterizedTypeReference<List<User>>() {}; // ResponseEntity:封装了返回值的信息 ResponseEntity<List<User>> response = rt.exchange(sb.toString(), HttpMethod.GET,null,type); List<User> list = response.getBody(); return list; } } |
注意配置文件中注册中心同样需要认证!
启动消费者,然后去注册中心查看
3.测试
访问消费者提供的服务
多次访问查看控制台输出
通过输出我们能发现负载均衡是通过轮询的方式实现的(默认)
注意在Windows下的hosts中添加对应的主机名和ip的映射关系!