微服务系统化学习笔记
本帖最后由 yx548634898 于 2022-8-26 23:03 编辑目前微服务比较火,自身也有用到,不过鉴于自身使用是只是未有系统化学习,所以近期想系统化学习下微服务的。立个帖子,主要目的是:
1、督促自己每日学习(不求每日大踏步,最少每日都有迈出一小步)
2、日常学习中总会有些问题与困难,想做个笔记。以便于日后查找。
楼层目录
附录:常用git命令……………………………………………5楼
实现服务远程调用-通过restTemplate实现…………6楼
注册中心-Eureka注册中心实现…………………………7楼 加油老哥,同是后端 本帖最后由 yx548634898 于 2022-9-15 10:00 编辑
码云仓库: https://gitee.com/yanhan-git/micro-service-demom
楼层目录
实现服务远程调用-通过restTemplate实现 ………………………………………………………………… 6楼码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.1.0-resttemplate
1)在order-service中添加user实体类
2)在Order实体类中添加user属性值
3)(关键)注册RestTemplate
4)在OrderService中实现通过http服务请求获取用户信息功能
注册中心-Eureka注册中心实现 …………………………………………………………………………………… 7楼码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.1-eureka
1)搭建eureka-server(作为客户端)
i)引入eureka依赖包(服务端)
ii)编写启动项&开启Eureka注册中心功能
iii)编写配置文件
2)服务注册
i)引入eureka依赖包(客户端)
ii)修改application.yml配置文件
iii)扩展知识(idea中一个应用同时启动多个服务)
3)服务发现
i)引入eureka依赖包(客户端)
ii)配置文件
iii)服务拉取和负载均衡
题外话)Eureka未配置不向自身注册或者获取信息配置踩坑说明 ……………………………… 9楼
扩展、自定义SpringCloud负载均衡机制(Ribbon负载均衡)&自定义机制的方法 …… 11楼 码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.EXTRA-ribbon
1)SpringCloud负载均衡实现方式
2)负载均衡策略
3)自定义负载均衡策略
i)使用在配置类中@Bean注解实现一个IRule实现方法
ii)通过配置文件指定修改某个服务的调用规则
iii)Ribbon加载模式修改
Nacos注册中心 ………………………………………………………………………………………………………… 12楼 码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.2-nacos
1)Nacos下载&安装
2)访问Nacos
3)服务注册到nacos
i)引入nacos依赖包
ii)配置nacos地址
Nacos注册中心扩展 ………………………………………………………………………………………………… 13楼 码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.2-nacos
1)服务分级存储模型
i)配置集群
ii)user-service应用多开(模拟)
iii)同集群优先的负载均衡配置
2)权重配置
3)环境隔离
i)创建namespace
ii)给微服务配置namespace
4)实例类型
i)临时实例
ii)非临时实例(永久实例)
Nacos和Eureka比较 ………………………………………………………………………………………………… 13楼
Nacos注册中心-配置管理 ………………………………………………………………………………………………… 14楼 码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.2-nacos-ext
1)统一配置管理
i)在nacos中添加配置文件
ii)从微服务拉取配置
2)配置热更新
i)添加配置动态刷新注解
ii)使用配置属性类
3)配置共享
i)添加一个环境共享配置
ii)在user-service中读取共享配置
iii)运行两个UserApplication,使用不同的profile
4)配置共享的优先级
Feign远程调用 ………………………………………………………………………………………………… 15楼 码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.3-feign-ext
1、使用Feign替代RestTemplate
1)引入依赖
2)添加注解
3)编写Feign的客户端
4)使用 Feign 客户端进行远程调用
5)总结
2、自定义配置
1)配置文件方式
2)Java代码方式
3、Feign直接调用url链接(为了解Feign自我测试)
4、最佳实践
1)继承方式
2)抽取方式
3)实现基于抽取的最佳实践
i)抽取
ii)在order-service中使用feign-api
iii)重启测试
iv)解决扫描包问题
5、Feign使用优化
1)引入依赖
2)配置连接池
Gateway服务网关 ………………………………………………………………………………………………… 16楼 码云仓库路径:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.4-gateway
1、gateway快速入门
1)创建gateway服务,引入依赖
2)编写启动类
3)编写基础配置和路由规则
4)重启测试
5)网关路由的流程图
2、断言工厂
1)断言工厂描述
2)查看gateway官方手册
3、过滤器工厂
1)路由过滤器的种类
2)请求头过滤器
3)默认过滤器
4)总结
4、全局过滤器
1)全局过滤器作用
2)自定义全局过滤器
3)过滤器执行顺序
5、跨域问题
1)什么是跨域问题
2)模拟跨域问题
3)解决跨域问题附录1:常用git命令 …………………………………………………………………………………………………… 5楼
1、查看分支列表
2、查看当前分支状态
3、创建分支
4、删除分支(本地)
5、提交分支到远程仓库
6、删除分支(远程)
7、合并分支(将指定分支合并到当前分支,可直接合并远程分支)
8、查看标签列表
9、新建tag标签
10、提交tag标签
11、删除本地tag标签
12、删除远程tag标签 (注意 空格)
13、新建一个分支,指向某个tag标签
附录2:Eureka配置详解(网络资料引用仅作参考) ……………………………………………… 10楼 加油!
.net 系的话,或许我能帮点小忙~ 本帖最后由 yx548634898 于 2022-8-27 15:58 编辑
# 附录1:常用git命令
## 1、查看分支列表
**git命令详解**
```shell
# 列出所有本地分支
git branch
# 列出所有远程分支
git branch -r
# 列出所有本地分支和远程分支
git branch -a
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (feature-resttemplate)
$ git branch
feature-eureka
* feature-resttemplate
master
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (feature-resttemplate)
$ git branch -r
origin/feature-eureka
origin/feature-resttemplate
origin/master
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (feature-resttemplate)
$ git branch -a
feature-eureka
* feature-resttemplate
master
remotes/origin/feature-eureka
remotes/origin/feature-resttemplate
remotes/origin/master
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (feature-resttemplate)
$
```
其中,分支前的*表示当前处在哪个分支
## 2、查看当前分支状态
**git命令详解**
```shell
# 查看状态
git status
# 查看状态 使输出信息更加简洁
git status –s
```
**具体示例**
存在未提交文件
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (feature-resttemplate)
$ git status
On branch feature-resttemplate
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.md
no changes added to commit (use "git add" and/or "git commit -a")
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (feature-resttemplate)
$ git status -s
M readme.md
```
无任何需要提交文件
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
$ git status
On branch feature-test
nothing to commit, working tree clean
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
$ git status -s
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
```
## 3、创建分支
**git命令详解**
```shell
# 创建分支
git branch <分支名>
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git branch feature-test
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
```
## 4、删除分支(本地)
**git命令详解**
```shell
# 删除分支(如果分支已经修改过,则不允许删除)
git branch -d<分支名>
# 强制删除分支
git branch -D<分支名>
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git branch -d feature-test
Deleted branch feature-test (was 89a11e6).
```
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git branch -d feature-test
error: The branch 'feature-test' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-test'.
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git branch -D feature-test
Deleted branch feature-test (was 4546a15).
```
## 5、提交分支到远程仓库
**git命令详解**
```shell
# 提交分支至远程仓库
git push <仓库简称> <分支名称>
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
$ git push origin feature-test
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM
remote: Create a pull request for 'feature-test' on Gitee by visiting:
remote: https://gitee.com/yanhan-git/micro-service-demom/pull/new/yanhan-git:feature-test...yanhan-git:master
To https://gitee.com/yanhan-git/micro-service-demom.git
* feature-test -> feature-test
```
## 6、删除分支(远程)
**git命令详解**
```shell
# 删除远程仓库分支
git push <仓库简称> –d <分支名称>
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
$ git push origin -d feature-test
remote: Powered by GITEE.COM
To https://gitee.com/yanhan-git/micro-service-demom.git
- feature-test
```
## 7、合并分支(将指定分支合并到当前分支,可直接合并远程分支)
**git命令详解**
```shell
# 合并分支 将其他分支合并至当前工作区
git merge <分支名称>
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
$ git branch -a
* feature-test
master
remotes/origin/HEAD -> origin/master
remotes/origin/feature-eureka
remotes/origin/feature-resttemplate
remotes/origin/feature-test
remotes/origin/master
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
$ git merge remotes/origin/feature-resttemplate
Updating 89a11e6..4546a15
Fast-forward
assets/1661432091821.png | Bin 0 -> 13973 bytes
……中间省略大量记录……
assets/1661459606134.png | Bin 0 -> 15136 bytes
.../java/cn/yanhan/order/OrderApplication.java | 7 ++
.../java/cn/yanhan/order/mapper/OrderMapper.java | 3 +-
.../src/main/java/cn/yanhan/order/pojo/Order.java| 6 +-
.../src/main/java/cn/yanhan/order/pojo/User.java |10 +++
.../java/cn/yanhan/order/service/OrderService.java |18 ++++-
order-service/src/main/resources/application.yml | 6 +-
readme.md |75 +++++++++++++++++++--
.../src/main/java/cn/yanhan/user/pojo/User.java | 2 +-
20 files changed, 116 insertions(+), 11 deletions(-)
create mode 100644 assets/1661432091821.png
……中间省略大量记录……
create mode 100644 assets/1661459606134.png
create mode 100644 order-service/src/main/java/cn/yanhan/order/pojo/User.java
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
$ git push origin -d feature-test
remote: Powered by GITEE.COM
To https://gitee.com/yanhan-git/micro-service-demom.git
- feature-test
```
## 8、查看标签列表
**git命令详解**
```shell
# 列出所有tag
git tag
# 查看tag详细信息
git show
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (master)
$ git tag
0.0.0-initialize
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (master)
$ git show 0.0.0-initialize
tag 0.0.0-initialize
Tagger: YanHan <YanHan>
Date: Thu Aug 25 10:48:14 2022 +0800
初始化版本标签
commit 9c4b707304985d2e6a080b1776600fb32ea6a801 (tag: 0.0.0-initialize)
Author: YanHan <YanHan>
Date: Tue Aug 23 00:43:45 2022 +0800
项目初始化
:
tag 0.0.0-initialize
Tagger: YanHan <YanHan>
Date: Thu Aug 25 10:48:14 2022 +0800
初始化版本标签
commit 9c4b707304985d2e6a080b1776600fb32ea6a801 (tag: 0.0.0-initialize)
Author: YanHan <YanHan>
Date: Tue Aug 23 00:43:45 2022 +0800
项目初始化
```
## 9、新建tag标签
**git命令详解**
```shell
# 新建一个tag
git tag
# 新建一个tag,并添加描述信息
git tag -m
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (master)
$ git tag 1.1.0-resttemplate -m "服务远程调用-通过RestTemplate实现http请求方式的远程调用"
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (master)
```
## 10、提交tag标签
**git命令详解**
```shell
# 提交指定tag
$ git push [仓库简称]
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/cloud-demo (master)
$ git push origin 1.1.0-resttemplate
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 225 bytes | 225.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM
To https://gitee.com/yanhan-git/micro-service-demom.git
* 1.1.0-resttemplate -> 1.1.0-resttemplate
```
## 11、删除本地tag标签
**git命令详解**
```shell
# 删除本地tag
$ git tag -d
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git tag 0.0.1-test -m "测试用tag"
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git tag -d 0.0.1-test
Deleted tag '0.0.1-test' (was 0c61498)
```
## 12、删除远程tag标签 (注意 空格)
**git命令详解**
```shell
# 删除远程tag (注意 空格)
$ git push origin :refs/tags/
# 删除远程tag (注意 空格)
$ git push origin -d
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git push origin :refs/tags/0.0.1-test
remote: Powered by GITEE.COM
To https://gitee.com/yanhan-git/micro-service-demom.git
- 0.0.1-test
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git push origin -d 0.0.1-test
remote: Powered by GITEE.COM
To https://gitee.com/yanhan-git/micro-service-demom.git
- 0.0.1-test
```
## 13、新建一个分支,指向某个tag标签
**git命令详解**
```shell
# 新建一个分支,指向某个tag
$ git checkout -b
```
**具体示例**
```shell
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git tag
0.0.0-initialize
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git branch
* master
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (master)
$ git checkout -b feature-test 0.0.0-initialize
Switched to a new branch 'feature-test'
Administrator@Administrator MINGW64 /d/DevWorkSpaces/版本情况验证/micro-service-demom (feature-test)
```
根据tag标签创建分支,并切换到新建分支下 本帖最后由 yx548634898 于 2022-8-26 23:01 编辑
# 实现服务远程调用
user-service、order-service两模块数据彼此隔离,现需实现order-service通过userid关联获取用户信息
## 通过restTemplate实现
**原理:**既然服务可以通过http服务地址访问,则可使用RestTemplate(Spring自带的http请求工具来实现)在order-service中通过http://localhost:8081/user/1服务地址获取用户信息。
### 1)在order-service中添加user实体类
### 2)在Order实体类中添加user属性值
!(assets/1661433228830.png)
### 3)(关键)注册RestTemplate
需要将RestTemplate注册到启动类中,在项目启动时加载RestTemplate的bean。否则会出现的异常。
> Field restTemplate in cn.yanhan.order.service.OrderService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
在启动类OrderApplication中注册RestTemplate bean。
```
@Bean
public RestTemplate restTemplate () {
return new RestTemplate();
}
```
### 4)在OrderService中实现通过http服务请求获取用户信息功能
```
// 1. 查询订单
//return orderMapper.findById(id);
Order order = orderMapper.findById(id);
// 2. 远程调用。利用RestTemplate发起http请求,查询用户
// 2.1. 拼接url地址 http://localhost:8081/user/{userId}
String url = "http://localhost:8081/user/" + order.getUserId();
// 2.2.发送http请求,实现远程调用
User user = restTemplate.getForObject(url, User.class); // 通过url服务获取数据,并将数据转换为USER类型
// 3.封装user到Order
order.setUser(user);
// 4.返回
return order;
```
### 结果
!(assets/1661459606134.png) 本帖最后由 yx548634898 于 2022-8-27 16:12 编辑
# 注册中心
## 1、Eureka注册中心
通过RestTemplate使用http请求的方式调用远程服务,业务需明确知道对应服务IP端口信息等问题,如有多个服务负载均衡,相对不便(通过Nginx也可变通实现负载均衡,此处不做讲解),而且代码不美观。
- order-service在发起远程调用的时候,该如何得知user-service实例的ip地址和端口?
- 有多个user-service实例地址,order-service调用时该如何选择?
- order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?
为更好的解决上述问题,引入SpringCloud的注册中心功能。其中最广为人知的注册中心就是Eureka,其结构如下:
!(assets/1661503403061.png)
### 1)搭建eureka-server(作为服务端)
新建模块命名为eureka-server
#### i)引入eureka依赖包(服务端)
```xml
<!-- Eureka服务端依赖包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
```
**特别说明:**Eureka为Springcloud服务,依赖于SpringCloud依赖包,本项目就是使用SpringCloud搭建微服务项目,故须在父模块的pom.xml中添加SpringCloud依赖包,以便于子模块都能使用到该依赖包
```xml
<!-- springCloud 依赖包,使用SpringCloud组件需要添加本依赖。如:Eureka就需要依赖于这个包。-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
```
另外:SpringCloud与SpringBoot有版本依赖关系
!(assets/1661506572518.png)
#### ii)编写启动项&开启Eureka注册中心功能
编写个SpringBoot启动项。
**特别说明:**启动项需添加@EnableEurekaServer注解,从而达到开启eureka的注册中心功能的目的。
```java
package cn.yanhan.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer //开启Eureka服务功能
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
```
#### iii)编写配置文件
SpringBoot项目必不可少的是application.yml配置文件,在配置文件中配置Eureka服务信息
```yaml
server:
port: 10086
spring:
application:
name: eureka-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
```
完成上述最简单的SpringBoot三步走,就可以启动一个最简单的Eureka服务了。效果
!(assets/1661508047641.png)
### 2)服务注册
如上,Eureka搭建好后,其他服务想要通过Eureka进行管理的,只需把服务信息送给Eureka即可。此处叫做服务注册。
#### i)引入eureka依赖包(客户端)
本项目user-service需要请,eureka进行服务管理,在user-service的pom.xml中添加依赖包
```xml
<!-- <!– Eureka客户端依赖包(不是导入这个别错了) –>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-netflix-eureka-client</artifactId>-->
<!-- </dependency>-->
<!-- Eureka客户端依赖包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
```
注意:有两个相似的包,别导错了。
#### ii)修改application.yml配置文件
在user-serviceapplication.yml配置中添加eureka服务地址信息,达到将服务注册到eureka的目的。
```xml
<!-- Eureka客户端依赖包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
</dependency>
```
重载下项目,重启服务即可在eureka中看到user-service服务了。
#### iii)扩展知识(idea中一个应用同时启动多个服务)
> 右键需要启动多个的应用。选择“复制配置... Ctrl+D”,弹出应用配置。
!(assets/1661509781905.png)
> 在“VM选项”中添加新的端口配置,避开已使用的端口。配置示例: -Dserver.port=8082
!(assets/1661509906417.png)
查看eureka页面即可看到多个服务
!(assets/1661510056142.png)
注:上图Application下面的名字为unknown,说明我们的user-service服务中忘记配置服务名了。配置下。
```yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 需要在pom中导入驱动包
application: # 此处漏了
name: userserver
```
重启服务,看eureka页面结果
!(assets/1661510658005.png)
!(assets/1661510708506.png)
!(assets/1661510738690.png)
Eureka服务地址不会直接删除之前注册的服务,只有在客户端服务心跳测试后,会删除。(理论是30秒一次心跳,本次观察好像不止30秒)。
又是三步走,搭好了user-service服务。
### 3)服务发现
上文两点,搭好了Eureka以及user-service。现在就要搭下使用服务使用方order-service的服务了。
此处我们需要从Eureka注册中心中拉取所需服务。也是三步走。
#### i)引入eureka依赖包(客户端)
和uer-service一样,对于eureka来说,他们都是客户端(Eureka服务的使用者、消费者)。所以在pom.xml中引入eureka依赖包(客户端)
```xml
<!-- Eureka客户端依赖包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
```
#### ii)配置文件
服务发现也需要知道eureka地址,因此第二步与服务注册一致,都是配置eureka信息:
在order-service中,修改application.yml文件,添加服务名称、eureka地址:
```yaml
eureka:
client:
service-url: # 配置eureka地址信息,达到将服务注册到eureka的目的
defaultZone: http://127.0.0.1:10086/eureka
```
不加配置信息的化,order-service不知道去哪个服务地址拿服务信息
#### iii)服务拉取和负载均衡
我们从eureka-server中拉取user-service服务的实例列表,并且实现负载均衡。此处仅需使用注解即可。
在order-service的OrderApplication中,给RestTemplate这个Bean添加一个@LoadBalanced注解
```java
@Bean
@LoadBalanced
public RestTemplate restTemplate () {
return new RestTemplate();
}
```
修改order-service服务中的cn.yanhan.order.service包下的OrderService类中的queryOrderById方法。用服务名代替ip、端口:
```java
public Order queryById (Long id) {
// 1. 查询订单
//return orderMapper.findById(id);
Order order = orderMapper.findById(id);
// 2. 远程调用。利用RestTemplate发起http请求,查询用户
// 2.1. 拼接url地址 http://localhost:8081/user/{userId}
//String url = "http://localhost:8081/user/" + order.getUserId();
String url = "http://userserver/user/" + order.getUserId(); // 用eureka上看到的服务名替代localhost:8081
// 2.2.发送http请求,实现远程调用
User user = restTemplate.getForObject(url, User.class); // 通过url服务获取数据,并将数据转换为USER类型
// 3.封装user到Order
order.setUser(user);
// 4.返回
return order;
}
```
结果:
!(assets/1661521567295.png) eureka注册中心示例,码云源码:https://gitee.com/yanhan-git/micro-service-demom/tree/1.2.1-eureka #### 题外话)Eureka未配置不向自身注册或者获取信息配置踩坑说明
因为application.yml配置文件在项目启动之初就回去加载,如果Eureka未配置不向自身注册或者获取信息。在项目运行之初就会有报错。项目会在“未成功注册”或者“未成功获取到注册信息”时,不断的发起“Getting all instance registry info from the eureka server”获取请求。
此时就会出现项目启动之初报错,项目启动好后,无其他异常报错的情况而且功能也无任何异常。
具体启动日志如下:
```java
2022-08-27 15:00:37.361INFO 13184 --- [ main] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
2022-08-27 15:00:39.426INFO 13184 --- [ main] c.n.d.s.t.d.RedirectingEurekaHttpClient: Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://127.0.0.1:10086/eureka/}, exception=java.net.ConnectException: Connection refused: connect stacktrace=com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
```
项目启动好后,还会多次"Getting all instance registry info from the eureka server"获取信息
```java
2022-08-27 15:00:39.692INFO 13184 --- [ main] cn.yanhan.eureka.EurekaApplication : Started EurekaApplication in 5.403 seconds (JVM running for 5.899)
……中间省略多字……
2022-08-27 15:01:39.482INFO 13184 --- com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
……中间省略多字……
2022-08-27 15:02:09.512INFO 13184 --- com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
……中间省略多字……
```
这很影响对项目的BUG的分析定位,这里添加两个配置,避免启动时报错。
```yaml
server:
port: 10086
spring:
application:
name: eurekaserver
eureka:
client:
service-url: # 配置eureka地址信息,达到将服务注册到eureka的目的
defaultZone: http://127.0.0.1:10086/eureka
# 是否向注册中心注册自己,缺省: true, 一般情况下,Eureka服务端是不需要再注册自己的
register-with-eureka: false
# 是否从Eureka获取注册信息,缺省: true
# 一般情况下,Eureka服务端是不需要的
fetch-registry: false
```
效果
!(assets/1661585701834.png) 本帖最后由 yx548634898 于 2022-8-27 15:48 编辑
# 附录:Eureka配置详解(网络资料引用仅作参考)
参考引用自: https://blog.csdn.net/qq_37604054/article/details/121068579
正确性尚未考证,仅作参考
```yaml
eureka:
# 实例配置
instance:
# 客户端在注册时使用自己的IP而不是主机名,缺省: false
prefer-ip-address: true
# 用实例IP
ip-address: ${spring.cloud.client.ip-address}
# Eureka客户端向服务端发送心跳的时间间隔,单位: 秒,默认: 30
lease-renewal-interval-in-seconds: 30
# Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒。
# 超过该时间之后服务端会将该服务实例从服务清单中剔除,从而禁止服务调用请求被发送到该实例上
lease-expiration-duration-in-seconds: 90
# ????????spring.application.name?????????unknown
appname: eureka-server
# 服务名,默认取spring.application.name的配置值,如果没有则为unknown
hostname: localhost
# 状态页面的URL,相对路径,默认使用 HTTP 访问,如需使用 HTTPS则要使用绝对路径配置,默认: /info
status-page-url-path: /info
# 健康检查页面的URL,相对路径,默认使用 HTTP 访问,如需使用 HTTPS则要使用绝对路径配置,默认: /health
health-check-url-path: /health
# 客户端配置
client:
# Eureka服务器的地址,类型为HashMap,默认的Key为 defaultZone;默认的Value为 http://localhost:8761/eureka
# 如果服务注册中心为高可用集群时,多个注册中心地址以逗号分隔。
service-url:
defaultZone: http://localhost:8762/eureka
# 是否向注册中心注册自己,缺省: true, 一般情况下,Eureka服务端是不需要再注册自己的
register-with-eureka: true
# 是否从Eureka获取注册信息,缺省: true
# 一般情况下,Eureka服务端是不需要的
fetch-registry: true
# 客户端拉取服务注册信息间隔,单位: 秒,缺省: 30
registry-fetch-interval-seconds: 30
# 是否启用客户端健康检查
healthcheck:
enabled: false
# 更新实例信息的变化到Eureka服务端的间隔时间,单位为秒
instance-info-replication-interval-seconds: 30
# 初始化实例信息到Eureka服务端的间隔时间,单位为秒
initial-instance-info-replication-interval-seconds: 30
# 轮询Eureka服务端地址更改的间隔时间,单位为秒。当我们与Spring CLoud Config整合,
# 动态刷新Eureka的serviceURL地址时需要关注该参数
eureka-service-url-poll-interval-seconds: 300
# 读取Eureka Server信息的超时时间,单位为秒
eureka-server-read-timeout-seconds: 30
# 链接Eureka Server的超时时间,单位为秒
eureka-server-connect-timeout-seconds: 5
# server端配置
server:
# 是否允许开启自我保护模式,当eureka服务器在短时间丢失过多客户端时,
# 自我保护模式可以使服务端不在删除失去连接的客户端,默认: true
enable-self-preservation: true
# Peer节点更新间隔,单位毫秒
peer-eureka-nodes-update-interval-ms: 4000
# eureka服务器清理无效节点的时间间隔,单位: 毫秒,默认: 60000
eviction-interval-timer-in-ms: 60000
```
页:
[1]
2