文章目录

  • 一、前置说明及其框架搭建
    • 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小项目-啥?小白都能看懂?相关推荐

  1. 【前端】零基础带你入门前端< 三 > —— 实现手机通讯录(微信通讯录)等

    零基础带你入门前端 描述类标签 查看手机通讯录 移动端进行查看 浮动 粘性定位 锚点定位 固定定位 实现手机通讯录 完结 前言: 此文章是在 < 一 >与 < 二 >的基础之上 ...

  2. 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)

    大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...

  3. micropython视频_零基础如何优雅入门“网红”Python?小白必看的MicroPython视频合集:从入门到精通!...

    零基础如何优雅入门"网红"Python?小白必看的MicroPython视频合集:从入门到精通! 若问时下最火的一门编程语言是什么?答案一定是Python. 就连高考都开始考Pyt ...

  4. 随机森林的特征 是放回抽样么_机器学习超详细实践攻略(10):随机森林算法详解及小白都能看懂的调参指南...

    一.什么是随机森林 前面我们已经介绍了决策树的基本原理和使用.但是决策树有一个很大的缺陷:因为决策树会非常细致地划分样本,如果决策树分得太多细致,会导致其在训练集上出现过拟合,而如果决策树粗略地划分样 ...

  5. 小白都能看懂的缓存入门

    缓存是程序员必须了解的技术,无论是前端.后端还是客户端,大到复杂的系统架构,小到 CPU 或是芯片,都少不了缓存的影子. 下面只需 5 分钟,带你入门缓存技术. 什么是缓存? 缓存(Cache)本意是 ...

  6. 零基础带你快速入门Ribbon技术(浅显易懂、小白都能看懂)

    xmind文档下载地址:https://download.csdn.net/download/Kevinnsm/19024681 赠(2021Java后端技术体系)下载地址: https://down ...

  7. 如何10分钟零基础实现Web3D(在线3D模型可视化)

    安装 http-server 第一步:点击链接 https://nodejs.org/dist/latest-v10.x/node-v10.17.0-x86.msi 下载 nodejs 并安装 第二步 ...

  8. 零基础学Python入门教程非常详细(从小白到高级)

    目录:基础 第一章-第五章(5.1-5.4):简介.配置与基础知识 第六章:判断语句 第一章:Python的概述 1.1:什么是Python? Python它是一种直译式,面向对象,解释式的脚本语言. ...

  9. 零基础如何快速入门微信小游戏开发?

    随着微信生态中,小程序应用指数级的增长,许多休闲游戏变成为了众多游戏厂商流量变现的新手段.以近期很火的"羊了个羊"为例,它便是我们常常所说的小游戏. 游戏和小游戏的区别 要盘点小游 ...

最新文章

  1. Delphi XE 10.2.3使用CEF4Delphi取网页元素时碰到nbsp;变问号?的处理
  2. 【机器学习入门笔记7:TensorFlow常量变量的定义】20190210
  3. 【知识图谱】知识推理,知识图谱里最“人工智能”的一段
  4. C语言中float double等类型在内存中的存储
  5. html中的时间代码怎么写,html网页代码中的时间样式怎样设置
  6. (2,1,3)卷积码与一种QC-LDPC码的译码性能对比
  7. hihocoder1543 SCI表示法
  8. 关于NPN和PNP传感器的应用区别(转载)
  9. 最近都在谈的「私域流量」,究竟有没有前途?
  10. OSTU大律法二值化原理
  11. [JavaScript] js 判断闰年
  12. 现在离开哈尔滨需要做核酸检测吗?
  13. 动易 dw css不对,动易模板制作示.doc
  14. 力扣报错 error: <identifier> expected
  15. Excel — 动态图表(复选框实现动态图)
  16. 用Python制作动态饼图
  17. Unity用代码批量修复材质球shader丢失的问题
  18. jsp高校学生宿舍公寓管理系统功能最全
  19. 移动端H5(JavaScript)识别二维码功能
  20. 通过平面向量角度认知世界

热门文章

  1. 腾讯2013年校园招聘笔试试题
  2. java怎么设置不同事件_activiti 全局流程监听ActivitiEventListener,实现监听不同类型事件,不需要在acitivit中配置任务监听,非常方便...
  3. java成果_JAVA WEB期末项目第二阶段成果
  4. rgb sw 线主板接口在哪_十代至尊i910980XE直接上:技嘉X299X AORUS MASTER主板评测
  5. zblog php搜索页面,Z-Blog PHP实现搜索分页
  6. java+synchro_synchrozied,wait()与notify()的理解
  7. 如何在文字上划横线_如何设计一张618促销海报?
  8. php cli mysql_php – 为什么mysql CLI可以连接,但不能连接WordPress?
  9. 地表离太空有多远_我国的子午工程都有哪些空间探测仪器?丨Calling太空
  10. mdkstc系列器件支持包下载_WPS Office 2019 For Linux(2020/10/21)更新-支持PDF编辑