10分钟零基础带你入门Ribbon小项目-啥?小白都能看懂?
文章目录
- 一、前置说明及其框架搭建
- 1、思路详解
- 2、框架搭建
- 二、代码编写
- 1、编写五个pom文件
- 1.1、父pom文件
- 1.2、子模块pom
- 2、编写启动类
- 3、application.yml文件编写
- 4、config文件配置
- 5、编写controller层
- 6、entity层
- 7、service层
- 三、测试
一、前置说明及其框架搭建
1、思路详解
由于设备限制,使用五个端口模拟五个服务(两个注册中心、两个服务提供者、一个服务消费者)其中两个注册中心用来演示Eureka集群的高可用,两个服务提供者用来演示Ribbon的负载均衡,一个服务消费者用来进行远程调用)
#当然官网中是以三个注册中心来演示Eureka集群高可用的,我用两个当然也可以。
如果你了解过zookeeper、consul或者nacos作为注册中心,这个对于你来说就比较简单了。
2、框架搭建
通过聚合工程来创建一个父工程和五个子模块
二、代码编写
1、编写五个pom文件
1.1、父pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.hao</groupId><artifactId>cloud-eureka-demo</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>cloud-eureka-server</module><module>cloud-eureka-server02</module><module>service-provider</module><module>service-consumer</module><module>service-provider02</module></modules><parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.4.3</version></parent><properties><spring-cloud.version>2020.0.2</spring-cloud.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>
父工程主要就一个cloud依赖和五个子模块以及继承的父依赖。
1.2、子模块pom
1、cloud-eureka-server、cloud-eureka-server02
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-eureka-demo</artifactId><groupId>com.hao</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-eureka-server</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency></dependencies>
</project>
这两个eureka注册模块pom不被我们熟知的依赖是spring-cloud-starter-netflix-eureka-server,这个依赖继承了eureka相关的所有包(包括Ribbon);导入spring-boot-starter-security的原因是对我们的注册中心客户端需要登录认证
2、service-consumer
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-eureka-demo</artifactId><groupId>com.hao</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>service-consumer</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>
这个spring-cloud-starter-netflix-eureka-client和上面的spring-cloud-starter-netflix-eureka-server是两种服务,从字面意思也应该都明白。
3、service-provider和service-provider02
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-eureka-demo</artifactId><groupId>com.hao</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>service-provider</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
</project>
2、编写启动类
1、eureka-server子模块的启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class);}
}
@EnableEurekaServer:该注解是自动识别为注册服务中心
2、eureka-server02子模块的启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication02 {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication02.class);}
}
3、service-consumer子模块启动类
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class);}
}
@EnableEurekaClient注解在最新版已经可以省略
4、service-provider子模块启动类
@SpringBootApplication
public class ProviderApplication {public static void main(String[] args) {SpringApplication.run(ProviderApplication.class);}
}
5、service-provider02子模块启动类
@SpringBootApplication
@EnableEurekaClient
public class Provider02Application {public static void main(String[] args) {SpringApplication.run(Provider02Application.class);}
}
3、application.yml文件编写
1、eureka-server子模块yml
server:port: 8080spring:application:name: cloud-eureka-serversecurity:user:name: rootpassword: root
eureka:instance:hostname: eureka01prefer-ip-address: trueinstance-id: ${spring.cloud.client.ip-address}:${server.port}client:service-url:defaultZone: http://root:root@127.0.0.1:${server.port}/eureka/ #注册中心对外暴露的注册地址
2、eureka-server02子模块yml
server:port: 8081spring:application:name: cloud-eureka-server02security:user:name: rootpassword: root
eureka:instance:hostname: eureka02prefer-ip-address: trueinstance-id: ${spring.cloud.client.ip-address}:${server.port}client:service-url:defaultZone: http://root:root@127.0.0.1:8080/eureka/
3、eureka-consumer子模块yml
server:port: 9090
spring:application:name: service-consumereureka:instance:hostname: consumerprefer-ip-address: trueinstance-id: http://${spring.cloud.client.ip-address}:${server.port}client:
# fetch-registry: false
# register-with-eureka: falseservice-url:defaultZone: http://root:root@127.0.0.1:8080/eureka/,http://root:root@127.0.0.1:8081/eureka/
4、service-provider子模块yml
server:port: 7070
spring:application:name: service-providereureka:instance:hostname: providerprefer-ip-address: trueinstance-id: http://${spring.cloud.client.ip-address}:${server.port}client:service-url:defaultZone: http://root:root@127.0.0.1:8080/eureka/,http://root:root@127.0.0.1:8081/eureka/
5、service-provider02子模块pom
server:port: 7071
spring:application:name: service-provider #集群下的名字是相同的eureka:instance:hostname: provider02prefer-ip-address: true #是否使用ip形式显示instance-id: http://${spring.cloud.client.ip-address}:${server.port}client:service-url:defaultZone: http://root:root@127.0.0.1:8080/eureka/,http://root:root@127.0.0.1:8081/eureka/
4、config文件配置
cloud-eureka-server 、cloud-eureka-server02
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//关闭某个path下的csrf,否者provider无法注册进去super.configure(http);http.csrf().ignoringAntMatchers("/eureka/**");}
}
service-consumer
@Configuration
public class ConsumerConfig {@Bean
// @LoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}
5、编写controller层
service-consumer
@RestController
public class OrderController {@Resourceprivate OrderService orderService;@GetMapping(value ="/order/{id}")public Order getOrderById(@PathVariable("id") Integer id) {return orderService.selectOrderById(id);}
}
service-provider 、service-provider02
@RestController
@RequestMapping(value = "/product")
public class ProductController {@Resourceprivate ProductService productService;@GetMapping(value = "/list")public List<Product> getProductList() {return productService.selectProductList();}
}
6、entity层
service-consumer
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {private Integer id;private String orderNo;private String orderAddress;private Double totalPrice;private List<Product> productList;}
service-provider 、service-provider02
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {private Integer id;private String productName;private Integer productNum;private Double productPrice;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {private Integer id;private String productName;private Integer productNum;private Double productPrice;
}
7、service层
service-consumer
public interface OrderService {Order selectOrderById(Integer id);
}
@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@Autowiredprivate LoadBalancerClient loadBalancerClient;@Overridepublic Order selectOrderById(Integer id) {return new Order(id, "order-1", "china", 1024D ,getProductListByLoadBalancerClient());}public List<Product> getProductListByDiscoveryClient() {StringBuffer sb = null;List<String> services = discoveryClient.getServices();if (CollectionUtils.isEmpty(services)) {return null;}//获取name为service-provider的服务实例List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");if (CollectionUtils.isEmpty(instances)) {return null;}ServiceInstance serviceInstance = instances.get(0);sb = new StringBuffer();//拼接地址sb.append("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/product/list");ResponseEntity<List<Product>> exchange = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, new ParameterizedTypeReference<List<Product>>() {});return exchange.getBody();}public List<Product> getProductListByLoadBalancerClient() {StringBuffer sb = null;ServiceInstance instance = loadBalancerClient.choose("service-provider");if (instance == null) {return null;}sb = new StringBuffer();sb.append("http://"+instance.getHost()+":"+instance.getPort()+"/product/list");System.out.println(instance.getHost()+":"+instance.getPort());ResponseEntity<List<Product>> exchange = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, new ParameterizedTypeReference<List<Product>>() {});return exchange.getBody();}public List<Product> getProductListByAnnotation() {ResponseEntity<List<Product>> exchange = restTemplate.exchange("http://service-provider/product/list", HttpMethod.GET, null, new ParameterizedTypeReference<List<Product>>() {});System.out.println(exchange);return exchange.getBody();}
}
这是演示的三种方式实现
service-provider 、service-provider02
public interface ProductService {List<Product> selectProductList();
}
@Service
public class ProductServiceImpl implements ProductService {@Overridepublic List<Product> selectProductList() {return Arrays.asList(new Product(1, "HuaWei nova3", 100, 2999.0),new Product(2, "xiaomi", 99, 1999.0),new Product(3, "vivo", 102, 2999.0));}
}
#使用Arrays.asList模拟返回数据
三、测试
访问http://localhost:8080/(账号和密码是在配置文件中配置的)
Eureka的高可用集群也搭建成功了
访问http://localhost:9090/order/1
服务间调用也成功!
下面多次刷新该页面,查看控制台打印结果
负载均衡!
10分钟零基础带你入门Ribbon小项目-啥?小白都能看懂?相关推荐
- 【前端】零基础带你入门前端< 三 > —— 实现手机通讯录(微信通讯录)等
零基础带你入门前端 描述类标签 查看手机通讯录 移动端进行查看 浮动 粘性定位 锚点定位 固定定位 实现手机通讯录 完结 前言: 此文章是在 < 一 >与 < 二 >的基础之上 ...
- 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)
大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...
- micropython视频_零基础如何优雅入门“网红”Python?小白必看的MicroPython视频合集:从入门到精通!...
零基础如何优雅入门"网红"Python?小白必看的MicroPython视频合集:从入门到精通! 若问时下最火的一门编程语言是什么?答案一定是Python. 就连高考都开始考Pyt ...
- 随机森林的特征 是放回抽样么_机器学习超详细实践攻略(10):随机森林算法详解及小白都能看懂的调参指南...
一.什么是随机森林 前面我们已经介绍了决策树的基本原理和使用.但是决策树有一个很大的缺陷:因为决策树会非常细致地划分样本,如果决策树分得太多细致,会导致其在训练集上出现过拟合,而如果决策树粗略地划分样 ...
- 小白都能看懂的缓存入门
缓存是程序员必须了解的技术,无论是前端.后端还是客户端,大到复杂的系统架构,小到 CPU 或是芯片,都少不了缓存的影子. 下面只需 5 分钟,带你入门缓存技术. 什么是缓存? 缓存(Cache)本意是 ...
- 零基础带你快速入门Ribbon技术(浅显易懂、小白都能看懂)
xmind文档下载地址:https://download.csdn.net/download/Kevinnsm/19024681 赠(2021Java后端技术体系)下载地址: https://down ...
- 如何10分钟零基础实现Web3D(在线3D模型可视化)
安装 http-server 第一步:点击链接 https://nodejs.org/dist/latest-v10.x/node-v10.17.0-x86.msi 下载 nodejs 并安装 第二步 ...
- 零基础学Python入门教程非常详细(从小白到高级)
目录:基础 第一章-第五章(5.1-5.4):简介.配置与基础知识 第六章:判断语句 第一章:Python的概述 1.1:什么是Python? Python它是一种直译式,面向对象,解释式的脚本语言. ...
- 零基础如何快速入门微信小游戏开发?
随着微信生态中,小程序应用指数级的增长,许多休闲游戏变成为了众多游戏厂商流量变现的新手段.以近期很火的"羊了个羊"为例,它便是我们常常所说的小游戏. 游戏和小游戏的区别 要盘点小游 ...
最新文章
- Delphi XE 10.2.3使用CEF4Delphi取网页元素时碰到nbsp;变问号?的处理
- 【机器学习入门笔记7:TensorFlow常量变量的定义】20190210
- 【知识图谱】知识推理,知识图谱里最“人工智能”的一段
- C语言中float double等类型在内存中的存储
- html中的时间代码怎么写,html网页代码中的时间样式怎样设置
- (2,1,3)卷积码与一种QC-LDPC码的译码性能对比
- hihocoder1543 SCI表示法
- 关于NPN和PNP传感器的应用区别(转载)
- 最近都在谈的「私域流量」,究竟有没有前途?
- OSTU大律法二值化原理
- [JavaScript] js 判断闰年
- 现在离开哈尔滨需要做核酸检测吗?
- 动易 dw css不对,动易模板制作示.doc
- 力扣报错 error: <identifier> expected
- Excel — 动态图表(复选框实现动态图)
- 用Python制作动态饼图
- Unity用代码批量修复材质球shader丢失的问题
- jsp高校学生宿舍公寓管理系统功能最全
- 移动端H5(JavaScript)识别二维码功能
- 通过平面向量角度认知世界
热门文章
- 腾讯2013年校园招聘笔试试题
- java怎么设置不同事件_activiti 全局流程监听ActivitiEventListener,实现监听不同类型事件,不需要在acitivit中配置任务监听,非常方便...
- java成果_JAVA WEB期末项目第二阶段成果
- rgb sw 线主板接口在哪_十代至尊i910980XE直接上:技嘉X299X AORUS MASTER主板评测
- zblog php搜索页面,Z-Blog PHP实现搜索分页
- java+synchro_synchrozied,wait()与notify()的理解
- 如何在文字上划横线_如何设计一张618促销海报?
- php cli mysql_php – 为什么mysql CLI可以连接,但不能连接WordPress?
- 地表离太空有多远_我国的子午工程都有哪些空间探测仪器?丨Calling太空
- mdkstc系列器件支持包下载_WPS Office 2019 For Linux(2020/10/21)更新-支持PDF编辑