SpringCloud 商城系统搭建之Ribbon (基于Ribbon + RestTemplate)

2023-11-04

Spring Cloud 服务调用方式

Spring Cloud有两种服务调用方式,一种是Ribbon + RestTemplate,另一种是feign。在这一篇文章首先讲解下基于Ribbon + RestTemplate。

Ribbon简介

Ribbon在Spring Cloud中担任着负载均衡的角色,它是一个基于HTTP和TCP的客户端负载均衡工具。Spring Cloud Ribbon只是一个工具类框架,它可以独立部署但是也不需要独立部署,它几乎存在于所有springcloud 构建的微服务和基础设施中。

Ribbon已经实现了负载均衡对象:

/**
*
* RoundRobinRule 轮询
* RandomRule 随机
* AvailabilityFilteringRule 优先过滤因访问故障处于断路器跳闸的服务
* 以及并发连接数超过阈值的服务。然后对剩余的服务做轮询
*
* WeightedResponseTimeRule 根据平均响应时间计算所有服务的权重,响应时间越快的权重越大
* 选择几率越高。
*
* RetryRule 先按照轮询获取服务,如果获取服务失败,
* 在规定时间内会重试获取可用的服务
*
* BestAvailableRule 优先过滤因访问故障处于断路器跳闸的服务,
* 然后选择并发量最小的服务
*
* ZoneAvoidanceRule 默认规则,复合判断服务所在区域的性能,和服务的可用性选择服务器
*
*/

前提

本文是基于SpringCloud 商城系统搭建之eureka 

Ribbon集成

1、在supermarker-consume的RestTemplate对象上加上 @LoadBalanced注解 和实列化负载均衡策略

代码修改如下:

package com.zzg.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

@Configuration
public class RestConfig {
	@Bean
	@LoadBalanced //负载均衡标识
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
	
	@Bean // 负载均衡策略实列化
	public IRule getIRule(){
		// 负载均衡:随机策略
		return new RandomRule();
	}
}

2、创建两个生产者:supermarker-provider 和supermarker-provider-second

两个生产者的application.properties 大致如下:

server.port=8082
# 生产者应用名称 -
spring.application.name=provider
# 生产者实例名,同一个spring.application.name 名称唯一
eureka.instance.instance-id=provider1
        
eureka.client.register-with-eureka=true
# 和eureka服务器通讯的URL
eureka.client.service-url.defaultZone=http://localhost:8081/eureka/

# 设置心跳的时间间隔(默认是30秒)
eureka.instance.lease-renewal-interval-in-seconds=5
# eureka server 最后一次收到心跳时等待的时间,超时将会移除client(默认是90秒)
eureka.instance.lease-expiration-duration-in-seconds=3


#h2配置
#启用SQL语句的日志记录
spring.jpa.show-sql=true
#设置ddl模式
spring.jpa.hibernate.ddl-auto=update
##数据库连接设置
#配置h2数据库的连接地址
spring.datasource.url=jdbc:h2:mem:dbtest
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driverClassName=org.h2.Driver
##数据初始化设置
#进行该配置后,每次启动程序,程序都会运行resources/db/schema.sql文件,对数据库的结构进行操作。
spring.datasource.schema=classpath:db/schema.sql
#进行该配置后,每次启动程序,程序都会运行resources/db/data.sql文件,对数据库的数据操作。
spring.datasource.data=classpath:db/data.sql
##h2 web console设置
#表明使用的数据库平台是h2
spring.datasource.platform=h2
# 进行该配置后,h2 web consloe就可以在远程访问了。否则只能在本机访问。
spring.h2.console.settings.web-allow-others=true
#进行该配置,你就可以通过YOUR_URL/h2访问h2 web consloe。YOUR_URL是你程序的访问URl。
spring.h2.console.path=/h2
#进行该配置,程序开启时就会启动h2 web consloe。当然这是默认的,如果你不想在启动程序时启动h2 web consloe,那么就设置为false。
spring.h2.console.enabled=true

#spring-boot-actuator配置
#开放所有的web Endpoints
management.endpoints.web.exposure.include=*

注意:两个消费者除端口和实例id外其他都是一样的,这里就不再粘贴其他功能代码

3、修改两个生产者:supermarker-provider 和supermarker-provider-second 对外提供的接口

supermarker-provider

package com.zzg.controller;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.zzg.dao.UserRepository;
import com.zzg.entity.User;

@RestController
public class UserController {
	@Autowired
	private UserRepository userRepository;
	
	
	@Value("${server.port}")
	private int port;
	
	@GetMapping("/user/{id}")
    public User findById(@PathVariable Integer id) {
		System.out.println("---------------provider端口被调用--------------" + port);
		
        return userRepository.findOne(new Specification<User>() {
			
			@Override
			public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				// TODO Auto-generated method stub
				 List<Predicate> predicates = new ArrayList<Predicate>();
	             // 用户编号
	             predicates.add(criteriaBuilder.equal(root.<Integer> get("useId"), id));
	                
				return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
			}
		}).orElse(null);
    }

}

supermarker-provider-second

package com.zzg.controller;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.zzg.dao.UserRepository;
import com.zzg.entity.User;

@RestController
public class UserController {
	@Autowired
	private UserRepository userRepository;
	
	@Value("${server.port}")
	private int port;
	
	@GetMapping("/user/{id}")
    public User findById(@PathVariable Integer id) {
		System.out.println("---------------provider-second端口被调用--------------" + port);
		
        return userRepository.findOne(new Specification<User>() {
			
			@Override
			public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				// TODO Auto-generated method stub
				 List<Predicate> predicates = new ArrayList<Predicate>();
	             // 用户编号
	             predicates.add(criteriaBuilder.equal(root.<Integer> get("useId"), id));
	                
				return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
			}
		}).orElse(null);
    }

}

Ribbon 负载均衡功能测试

1、分别启动supermarker-eureka、二个生产者(supermarker-provider和supermarker-provider-second)和消费者(supermarker-consume)
supermarker-eureka启动后,看到如下界面证明二个生产者创建成功,会显示有二个生产者,左边红框内是生产者集群名称,消费者在通过IP和port调用生产者接口时都是通过集群名称调用的,右边红框是实例名称

2、通过消费者调用生产者

消费者调用生产者代码

package com.zzg.controller;

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.RestController;
import org.springframework.web.client.RestTemplate;

import com.zzg.entity.User;

@RestController
public class UserController {
	@Autowired
	private RestTemplate restTemplate;
	
	@GetMapping("/user/{id}")
    public User findById(@PathVariable Integer id) {
		return restTemplate.getForObject("http://provider/user/" + id, User.class);
	}

}

消费者启动成功后,通过浏览器访问:http://localhost:8083/user/1 发现两个生产者控制台输入如下信息截图:

 

 

说明基于:Ribbon + RestTemplate 负载均衡功能完结,

温馨提示:Ribbon默认采用的负载均衡策略是轮询

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringCloud 商城系统搭建之Ribbon (基于Ribbon + RestTemplate) 的相关文章

  • C# 中奇妙的函数–6. 五个序列聚合运算(Sum, Average, Min, Max,Aggregate)

    今天 我们将着眼于五个用于序列的聚合运算 很多时候当我们在对序列进行操作时 我们想要做基于这些序列执行某种汇总然后 计算结果 Enumerable 静态类的LINQ扩展方法可以做到这一点 就像之前大多数的LINQ扩展方法一样 这些是基于IE
  • 【Flutter 3-5】Flutter进阶教程——在Flutter中使用Lottie动画

    作者 弗拉德 来源 弗拉德 公众号 fulade me Lottie动画 在移动开发中总是需要展示一些动画特效 作为程序员的我们并不是很擅长用代码做动画 即便是有些动画可以实现 在跨平台的过程中也会因为API的差异性导致动画在各个平台中展示
  • VS2019企业版安装

    安装环境VMware Win7sp1 Net Framework 4 6 win7sp1update VS企业版下载地址 链接 https pan baidu com s 1ToBLr8sZJ9KbNKWG 6YREg 提取码 m9dr N

随机推荐

  • vue如何实现el-menu与el-tabs联动,通过点击el-menu导航中的选项动态添加el-tabs页面

    Vue如何实现el menu与el tabs联动 通过点击el menu导航中的选项动态添加tab页面 老规矩 先上效果图 达成这个效果 首先我们先了解下原理 在el menu中有一个属性router 开发文档中写的非常清晰 选择该属性后即
  • c#使用多线程的几种方式介绍

    本文主要介绍了c 使用多线程的几种方式 通过示例学习c 的多线程使用方式 大家参考使用吧 1 不需要传递参数 也不需要返回参数 ThreadStart是一个委托 这个委托的定义为void ThreadStart 没有参数与返回值 代码如下
  • Docker使用

    1 下载安装 在linux下安装docker一共有三步 更新软件包列表 sudo apt get update 安装docker sudo apt get install docker ce 检查docker是否安装成功 docker ve
  • MES管理系统项目失败的原因,总结三点

    MES是一款管理系统 建设效果参差不齐 但是MES管理系统项目以胜利的寥寥无几 因为MES管理系统 主要面向管理人员 管理人员希望打开工厂黑河 然而工厂的数据来源基本都是由执行层提供的 建设MES生产管理系统的诉求与国家统计局需求是一样的
  • Chat GPT介绍

    推荐一个在线使用网站 ChatGPT Next Web chatnext top 可以免费使用 但有次数限制 体验一下ChatGPT还是不错的 次数用完可以充钱28 8元成为永久会员 我不是打广告 我只想让更多的人体验和接触ChatGPT
  • android 难题,Android开发中遇到的难题与解决方案

    引用资源文件错误 导致运行失败 无法确定错误位置 解决方案 在Android Studio的Terminal控制台输入 gradlew compileDebugSources 获取webView的高度 public void initVie
  • [windows][UI] WM_MOUSEACTIVATE

    当用户单击一个非激活的顶级窗体 或非激活的顶级窗体的子窗体时 系统就会发送WM MOUSEACTIVATE消息 还包括其他消息 给顶级窗体或子窗体 该消息在WM NCHITTEST消息之后 但在button down消息之前 当把 WM M
  • swift 类型判断 Dictory Array

    一 类型的判断 1 is 的介绍 Swift 中类型的判断的关键词是 is is操作用来判断某一个对象是否是某一个特定的类 它会返回一个bool类型的值 2 is的使用方法 1 gt is 的一般判断 Swift 系统也会自动判断 类型的一
  • C++/Python程序读取命令行参数

    C 程序读取命令行参数 include
  • 傅里叶变换(FT)数学解析推导学习总结

    写在前面 本文是一篇非常容易理解 同时会很有收获的傅里叶变换推导教程 文章是学习B站DR CAN老师傅里叶级数和傅里叶变换系列课程后的学习总结 主要目的以个人复习巩固为主 同时也分享给大家一些心得以及非常好的一位老师 附上链接 DR CAN
  • 串口的基本定义以及RS232,RS485和UART,USAT,SPI的联系和区别

    1 什么是串口 一个bit一个bit传输数据的方式称之为串口 串行接口 2 串口的种类 同步串口 带有同步时钟线的串口传输方式 异步串口 不带同步时钟线的串口传输方式 需要双方约定传输速度 3 串口的组成 串口由物理电气层和协议层组成 3
  • java字符串判断相等_java判断字符串是否相等的方法

    java判断字符串是否相等的方法 1 java中字符串的比较 我们经常习惯性的写上if str1 str2 这种写法在java中可能会带来问题 example1 String a abc String b abc 那么a b将返回true
  • 转载:算力计算

    一 GOPS与FLOPS 1 1 FLOPS FLOPS定义 是 每秒所执行的浮点运算次数 floating point operations per second 的缩写 它常被用来估算电脑的执行效能 尤其是在使用到大量浮点运算的科学计算
  • 1334. 阈值距离内邻居最少的城市

    1334 阈值距离内邻居最少的城市 原题链接 完成情况 解题思路 参考代码 Dijkstra Dijkstra 小顶堆 Floyd martix方法 原题链接 1334 阈值距离内邻居最少的城市 https leetcode cn prob
  • 裸机服务器和虚拟机的用途和好处

    裸机服务器 用户可以根据需要自定义存储区域 用户几乎可以在世界的每个角落访问他们的数据 用户还将拥有最高级别的数据加密 只有使用最新技术的用户才能访问 由于这些服务器有专门的用户 因此具有安全性和监管优势 它具有很高的处理能力 用户可以完全
  • Poi版本升级优化

    Poi 3 17前后版本api使用差异 1 升级缘由 最近公司prod环境出现因为Excel文件下载数据量过大导致应用out of memory 然后就需要找到内存溢出的原因及优化方案 经分析 得出以下结论 1 1 事故原因 1 应用场景发
  • 四合天地软件测试系统,GZ-2017025软件测试赛题.-全国职业院校技能大赛.doc

    GZ 2017025软件测试赛题 全国职业院校技能大赛 doc 2017年全国职业院校技能大赛高职组 软件测试 项目竞赛任务书 2017年全国职业院校技能大赛 高职组 软件测试 赛项执委会制 2017年5月 目录 一 赛程说明3 二 竞赛技
  • ElasticSearch启动流程指令及注意事项

    elasticsearch es的集群部署 第一步 创建普通用户 注意 ES不能使用root用户来启动 必须使用普通用户来安装启动 这里我们创建一个普通用户以及定义一些常规目录用于存放我们的数据文件以及安装包等 创建一个es专门的用户 必须
  • 第一个python代码,第一个错误。python是对缩进严格要求的代码。

    在编写第一个条件判断语句的代码中 就遇到了第一个错误 运行py时提示 仔细对照了一下代码 发现原来时缩进格式错误 并很不明显 条件语句的if换行一般是缩进四个空格 但个人觉得以其按四个空格 不如直接按一下tab键来得简洁明了 我两种方法都试
  • SpringCloud 商城系统搭建之Ribbon (基于Ribbon + RestTemplate)

    Spring Cloud 服务调用方式 Spring Cloud有两种服务调用方式 一种是Ribbon RestTemplate 另一种是feign 在这一篇文章首先讲解下基于Ribbon RestTemplate Ribbon简介 Rib