[前端学java13-SpringCloud] Eureka + RestTemplate + Zuul + Ribbon

导航

[react] Hooks

[封装01-设计模式] 设计原则 和 工厂模式(简单抽象方法) 适配器模式 装饰器模式
[封装02-设计模式] 命令模式 享元模式 组合模式 代理模式

[React 从零实践01-后台] 代码分割
[React 从零实践02-后台] 权限控制
[React 从零实践03-后台] 自定义hooks
[React 从零实践04-后台] docker-compose 部署react+egg+nginx+mysql
[React 从零实践05-后台] Gitlab-CI使用Docker自动化部署

[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack – compiler简单编译流程
[源码] Redux React-Redux01
[源码] axios
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 – 初始化,访问,更新过程
[源码-vue03] watch 侦听属性 – 初始化和更新
[源码-vue04] Vue.set 和 vm.$set
[源码-vue05] Vue.extend

[源码-vue06] Vue.nextTick 和 vm.$nextTick
[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI

[数据结构和算法01] 二分查找和排序

[深入01] 执行上下文
[深入02] 原型链
[深入03] 继承
[深入04] 事件循环
[深入05] 柯里化 偏函数 函数记忆
[深入06] 隐式转换 和 运算符
[深入07] 浏览器缓存机制(http缓存机制)
[深入08] 前端安全
[深入09] 深浅拷贝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模块化
[深入13] 观察者模式 发布订阅模式 双向数据绑定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手写Promise
[深入20] 手写函数
[深入21] 数据结构和算法 – 二分查找和排序
[深入22] js和v8垃圾回收机制
[深入23] JS设计模式 – 代理,策略,单例

[前端学java01-SpringBoot实战] 环境配置和HelloWorld服务
[前端学java02-SpringBoot实战] mybatis + mysql 实现歌曲增删改查
[前端学java03-SpringBoot实战] lombok,日志,部署
[前端学java04-SpringBoot实战] 静态资源 + 拦截器 + 前后端文件上传
[前端学java05-SpringBoot实战] 常用注解 + redis实现统计功能
[前端学java06-SpringBoot实战] 注入 + Swagger2 3.0 + 单元测试JUnit5
[前端学java07-SpringBoot实战] IOC扫描器 + 事务 + Jackson
[前端学java08-SpringBoot实战总结1-7] 阶段性总结
[前端学java09-SpringBoot实战] 多模块配置 + Mybatis-plus + 单多模块打包部署
[前端学java10-SpringBoot实战] bean赋值转换 + 参数校验 + 全局异常处理
[前端学java11-SpringSecurity] 配置 + 内存 + 数据库 = 三种方式实现RBAC
[前端学java12-SpringSecurity] JWT
[前端学java13-SpringCloud] Eureka + RestTemplate + Zuul + Ribbon

(一) 前置知识

(1) 一些单词

assistant 助理
framework 框架 架构
replica 复制品 摹本
discovery 发现
ribbon 丝带

balance 平衡 均衡  //  @LoadBalanced // 声明一个基于Ribbon的负载均衡
复制代码

(2) 单体应用存在的问题

  • 随着业务越来越复杂,系统会越来越庞大
  • 一个模块出现问题,很可能造成整个业务系统崩溃
  • 多个团队对数据进行管理,容易产生安全漏洞
  • 各个模块都使用同一种技术,很难根据实际情况选择更适合的技术框架,局限性很大
  • 模块内容太复杂,成员变动需要很长时间才能完成工作交接

(3) ( 分布式 ) 和 ( 集群 )

  • 集群
    • ( 一台服务器 ) 无法负荷 ( 高并发的数据访问量 ),那么就用 ( 十台 ) 来 ( 分摊压力 )
    • 物理层面
  • 分布式
    • 将一个复杂的问题拆分成多个简单的小问题
    • 将一个 ( 大型的项目 ) 拆分成 ( 若干个微服务 ) 来 ( 协同完成 )
    • 软件设计层面

(4) 架构

  • spring cloud 架构图

image.png

  • 组件
    • 注册中心 Eruka
    • 负载均衡 Ribbon
    • 监控 Zipkin
    • 网关 zuul

image.png

(二) Spring Cloud

(1) 注册中心 Eureka

  • eureka 是发现了的意思
  • 注册中心也叫服务中心
  • 注册中心的作用
    • ( 注册中心 ) 上保存的是 ( 服务名 )
    • ( 已注册的服务 ) 可以通过 eureka 来获取 ( 其他服务的服务名 ),通过服务名来完成远程调用,这样 ( 某个服务换了IP ) 也不用在意,名字不变就行
    • 有了注册中心,任何一个服务都不能直接去调用,都需要通过注册中心来调用
  • 总结
    • ( Eureka ) 主要作用是 ( 服务注册 ) 和 ( 服务发现 )
    • ( Eureka ) 涉及到 ( 服务提供者provider ) 和 ( 服务消费者consumer )

(1.1) Eureka 基本架构

image.png

  • Eureka Server
    • 提供 服务注册 和 服务发现
  • Service Provider
    • 服务提供方
    • 将自身的服务注册到Eureka,从而使消费方能找到
  • Service Consumer
    • 服务消费方
    • 从Eurkea获取注册服务列表,从而能够消费服务

(三) 在srpingboot中使用spring cloud/Eureka

(1) 新建父工程

  • 父工程可以选择 ( Spring-Assistant ) 快速创建一个web服务工程,父工程中具有
    • spring-boot-starter-web
    • spring-boot-start-test

(2) 在父工程的pom.xml中添加springcloud相关的maven依赖

<properties>
    <!-- spring cloud 版本-->
    <spring.cloud-version>Hoxton.SR8</spring.cloud-version> 
</properties>

    <!-- 子模块需要显示的声明引用的模块,对包进行统一管理 -->
    <!-- spring-cloud-dependencies -->
<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>
复制代码

(3) 新建一个module,取名eurekaServer,修改子module的pom.xml

  • eureka 是注册中心,负责注册服务和提供服务等
  • 下面的pom.xml表示eurekaServer是注册中的server
在子module - eurekaServer 的pom.xml文件中添加
---

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>
复制代码

(4) 在子module-eurekaServer的resources中添加application.yml配置文件

eurekaServer/resources/application.yml
---

server:
  port: 8761
eureka:
  client:
    register-with-eureka: true # 是否注册自己,即是否将当前的 eureka server 作为client进行注册
    fetch-registry: false # 是否获取其他 eureka server 服务数据
    service-url:
      defaultZone: http://localhost:8761/eureka/ # 注册中心的访问地址
复制代码

(5) 在 eurekaServer 中添加启动类,并添加 @EnableEurekaServer 注解

@SpringBootApplication // springboot 服务入口启动类
@EnableEurekaServer // 声明该类是一个 eureka server 微服务,提供服务注册和服务发现功能,即注册中心
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
复制代码

(6) 从1-5步有一个 ( 巨坑 ),就是要保证 ( springBoot ) 和 ( springCloud ) 的 ( 版本要一致 ),不然会报错启动不了

image.png

image.png

(7) 启动 eurekaServer,访问在在application.yml中声明的配置中心地址

  • 访问:http://localhost:8761
  • 因为这里 注册中心 还没有注册任何服务,所以开启对自己的注册
    • egister-with-eureka: true
    • 服务开启:up
    • 服务关闭:down
  • 开启中,效果如下

image.png

(8) 有了配置中心,我们新建 eurekaClient 来提供服务

  • 新建module => eurekaClient
  • 在 eurekaClient 模块中的 pom.xml 中做如下配置
  • 在 eurekaClient 模块中的 application.yml 中配置client
  • 在 eurekaClient 模块中新建启动类 EurekaClientApplication
1. eurekaClient/pom.xml
---

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>
复制代码
2. eurekaClient/resources/application.yml
---

server:
  port: 8761
eureka:
  client:
    register-with-eureka: true # 是否注册自己,即是否将当前的 eureka server 作为client进行注册
    fetch-registry: false # 是否获取其他 eureka server 服务数据
    service-url:
      defaultZone: http://localhost:8761/eureka/ # 注册中心的访问地址
复制代码
3. eurekaClient/java/com/example/eurekaClient/EurekaClientApplication
---

@SpringBootApplication
public class EurekaClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }
}
复制代码
  • 访问效果如下

image.png

image.png

(四) RestTemplate

  • RestTemplate 是Spring框架提供的REST的服务组件,底层是对http请求和响应进行了封装,提供了访问ERST服务的方法,来简化代码开发
  • 这里需要注意一点
    • 就是通过RestTemplate连接的调用方不必在注册中心注册,因为调用服务谁都可以调用

(1) 继续创建子module – restTemplate – 然后创建启动类

  • RestTemplateApplication
resTemplate/java/com.example.restTemplate/RestTemplateApplication
---

@SpringBootApplication
public class RestTemplateApplication {
    public static void main(String[] args) {
        SpringApplication.run(RestTemplateApplication.class, args);
    }

    @Bean // 注册到容器中,则在别的类中可以通过@AutoWired注入
    public RestTemplate restTemplate() {
        return new RestTemplate(); // 返回 RestTemplate 的实例
    }
}
复制代码

(2) 在模块restTemplate新建controller,通过 restTemplate.getForObject 来调用注册中心中的服务

  • restTemplate.getForObject
  • 只需要知道服务提供的访问地址即可,不需要知道服务的名称等等
resTemplate/java/com.example.restTemplate/controller/UserController
---

@RestController
public class UserController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/service-user")
    public User getServiceUser() {
        // 通过 restTemplate.getForObject 调用注册中心的服务
        // 第一个参数是服务地址
        // 第二个参数是数据返回的接收类
        return restTemplate.getForObject("http://localhost:8010/user", User.class);
    }
}
复制代码

(3) 启动restTemplate,然后即可访问/service-use来访问到注册中心的服务

image.png

(五) 服务消费者 consumer

  • 创建新的子module/eurekaConsumer
  • 在子module/eurekaConsumer/pom.xml引入clound-client依赖
  • 在子module/eurekaConsumer/resouces/application.yml中配置eureka
  • 在java/com.example.eurekaConsumer/EurekaConsumerApplication启动类

(1) consumer和普通的普通module调用服务有什么区别?

  • 区别是 consumer 在注册中心注册了,而比如上面的restTemplate没有在注册中心注册
  • 虽然都可以调用注册中心注册的服务,但是restTemplate本身并没有在注册中心注册过

(2) 具体步骤如下

1. eurekaConsumer/pom.xml
---

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>
复制代码
2. eurekaConsumer/resouces/application.yml
---

server:
  port: 8030
spring:
  application:
    name: consumer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
复制代码
3. 在子module/eurekaConsumer/java/com.example.eurekaConsumer/EurekaConsumerApplication
---

@SpringBootApplication
public class EurekaConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaConsumerApplication.class, args);
    }
    
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
复制代码

image.png

(六) 服务网关 zuul

  • Zuul 是Netfix提供的开源的 ( API网关服务器 ),是客户端和服务端所有请求的 ( 中间层 ),对外开发一个API,将所有请求导入统一的入口,屏蔽了服务端的具体实现逻辑
  • Zuul 可以实现
    • 反向代理
    • 在网关内部实现 动态路由身份认证IP过滤数据监控,等功能
    • Zuul 自带负载均衡,可以修改服务提供者的代码

(1) 新建module/zuul,然后在pom.xml中添加 ( eureka-client ) 和 ( zuul ) 依赖

zuul/pom.xml
---

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
</dependencies>
复制代码

(2) 新建 zuul/src/main/resources/application.yml 并添加zuul规则

server:
  port: 8040
spring:
  application:
    name: gateway
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
zuul:
  routes:
    provider: /p/** # 给服务提供者 provider 设置映射

复制代码

(3) 创建启动类 ZuulApplication

// @EnableZuulProxy:包含了 @EnableZuulServers 设置该类是网关的启动类
// @EnableAutoConfiguration:可以帮助springBoot将所有符合条件@Configuration配置加载到当前IOC容器中
@EnableZuulProxy
@EnableAutoConfiguration
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }
}
复制代码

image.png

(七) Ribbon

  • 是负载均衡的一种解决方案,基于 Netflix Ribbon 实现
  • 在这册中心对Ribbon进行注册后,Ribbon就可以基于某种负载均衡算法,自动的帮助服务消费者调用接口,开发者也可以根据需求自定义Ribbon的负载均衡算法,
    • 轮询
    • 随机
    • 加权轮训
    • 加权随机
  • 在实际开发中Ribbon需要结合eureka来使用,Eureka Server提供所有可以调用的服务列表,Ribbon基于特定的负载均衡算法从这些服务中提供者中选择要调用的实例

(1) 具体过程

  • 新建module/ribbon
  • 在pom.xml中添加eureka-client依赖
  • 新建 application.yml 配置 端口,eureka等
  • 新建启动类,RibbonApplidation,注意注解 @LoadBalanced
    • @LoadBalanced 声明一个基于Ribbon的负载均衡
    • balance是均衡,平衡的意思
1. pom.xml
---

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>
复制代码
2. application.yml
---

server:
  port: 8060
spring:
  application:
    name: ribbon
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
复制代码
3. RibbonApplication
---

package com.example.ribbon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class RibbonApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
    }

    @Bean
    @LoadBalanced // 声明一个基于Ribbon的负载均衡
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
复制代码
4. controller/UserController
---


@RestController
public class UserController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/ribbon-user")
    public User getServiceUser() {
        // 通过 restTemplate.getForObject 调用注册中心的服务
        // 第一个参数是服务地址
        // 第二个参数是数据返回的接收类
        
        // 注意这里的写法和下面的等价,即可以使用注册中心的服务名代替服务提供的具体地址
        return restTemplate.getForObject("http://provider/user", User.class); 
        
        // return restTemplate.getForObject("http://localhost:8010/user", User.class);
    }
}
复制代码

image.png

image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享