第十三课:微服务基本知识-微服务调用及运行过程

3. 微服务调用及运行过程

3.1 为什么分析微服务过程调用

在实际的项目中,微服务之间涉及到业务代码的部分,调用逻辑非常复杂,对于工程师而言,熟悉组件之间的调用关系,方便以后业务模块开发,集群部署与自动化编排过程中有非常大的帮助(基础),并且能够非常清楚哪些应用应该对外,哪些可以不用对外以及服务是怎样存活。

  • 在微服务中涉及的组件:注册中心,配置中心,服务提供者,服务消费者,路由网关

3.1.1 本案例涉及的服务有以下几种

注册中心服务(nacos),配置中心服务(nacos),服务提供者(passport),服务消费者(restTemplate,Feign),路由网关服务(Spring Cloud Gateway)

3.2 组件服务调用基本流程

  • 客户端浏览器输入url
  • 访问网关负载均衡(7层,可以是nginx/haproxy)通过负载均衡分发请求到spring cloud gateway网关
  • 网关在即受到来自负载均衡的请求之后,根据url地址匹配到服务名称,调用后台的restTemplate服务
  • restTemplate在接收到来自网关的请求以后,通过注册中心查询到服务列表,将请求服务列表中的服务,最后返回结果。

avator

3.3 组件内部接口调用流程

负载均衡->网关->消费者->服务提供者

3.4 微服务实战(单机部署)

3.4.1 运行微服务

安装java环境
将java安装包(jdk1.8.0_192.tar.gz)传到主机/usr/local/下并解压缩
编辑环境变量/etc/profile

vim /etc/prolfie
export JAVA_HOME=/usr/local/jdk1.8.0_192
export JRE_HOME=/${JAVA_HOME}/jre
export PATH=${JAVA_HOME}/bin:$PATH
#应用
source /etc/profile

3.4.2 安装nacos(单机)

下载注册中心nacos

https://nacos.io/zh-cn/docs/what-is-nacos.html

wget https://github.com/alibaba/nacos/releases/download/1.1.4/nacos-server-1.1.4.tar.gz
tar zxvf nacos-server-1.1.4.tar.gz 
cd nacos/bin
sh startup.sh -m standalone

登陆访问页面
http://192.168.68.152:8848/nacos
username:nacos
password:nacos

导入配置文件
nacos_config_provider.zip ----> provider-passport-config.yaml
nacos_config_gateway.zip ----> spring-cloud-gateway.yaml
可以从页面修改配置文件中注册中心的IP地址
spring-cloud-gateway.yaml

        server-addr: 192.168.68.152:8848
        file-extension: yaml
      config:
        server-addr: 192.168.68.152:8848

provider-passport-config.yaml

server-addr: 192.168.68.152:8848

生产使用集群模式(至少3个节点)

  1. 安装mysql5.7.25(主从)
  2. 导入数据库(nacos-mysql.sql)
  3. 修改配置文件(application.properties cluster.conf)
  4. 启动(sh startup.sh)

3.4.3 安装redis

yum install epel-release -y
yum install redis -y
#修改密码
vim /etc/redis.conf
requirepass 123456
bind 0.0.0.0
#开机启动
systemctl enable redis
systemctl restart redis
systemctl status redis

查看端口监听

[root@localhost ~]# netstat -lantup | grep 6379
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      12850/redis-server  

修改配置文件spring-cloud-gateway.yaml

redis:
    host: 192.168.68.152
    port: 6379
    password: 123456

3.4.4 后台服务provider-passport

上传测试包

mkdir springcloud && cd springcloud
[root@localhost springcloud]# ll
total 449792
-rw-r--r-- 1 root root  91330721 Aug 26 10:18 consumer-feign-passport-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  90430214 Aug 26 10:28 consumer-passport-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 105609972 Aug 26 12:27 gateway-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  49134278 Aug 26 10:27 monitor-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  33651884 Aug 26 10:24 passport-demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  90419589 Aug 26 12:14 provider-passport-0.0.1-SNAPSHOT.jar

3.4.4.1 运行provide passport

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar provider-passport-0.0.1-SNAPSHOT.jar

3.4.4.2 服务注册

从页面查看我们刚才启动的passport服务已经注册到注册中心
avator

3.4.4.3 访问后台服务接口

http://192.168.68.152:8086/v1/auth/login
返回json内容如下:

{
msg: "demo passport api",
api: "/v1/auth/login",
type: "passportProvider",
status: 200
}

http://192.168.68.152:8086/passport
返回json内容如下:

{
msg: "后台服务passport",
api: "/passport",
type: "autoNacosConfig",
status: 200
}

2.4.4.4 验证配置中心修改配置功能

通过nacos页面修改配置文件provider-passport-config.yaml的内容后,再次调用后台服务接口,可以看出我们通过配置中心修改配置以后并不需要重启服务,配置即时生效。

#修改msg字段
data:
  msg: '后台服务passport-修改配置测试'

再次调用接口http://192.168.68.152:8086/passport

{
msg: "后台服务passport-修改配置测试",
api: "/passport",
type: "autoNacosConfig",
status: 200
}

注意:并不是所有的配置可以在不重启服务的情况下生效,比如数据库。

查看passport服务日志可以看到配置变更以后重新生效的过程
avator

如果能够使用nacos注册到注册中心则使用临时实例,否则使用永久实例

https://nacos.io/zh-cn/docs/open-api.html

类型 服务端 客户端
主动发送 配置文件发送,统一更新 发送心跳
被动接受 心跳信息 配置文件
客户端:
2020-08-27 09:50:24.077  INFO 20140 --- [ing.beat.sender] com.alibaba.nacos.client.naming          : [BEAT] [] [] send beat to server: {"cluster":"DEFAULT","dom":"provider-passport","ip":"192.168.68.152","metadata":{"preserved.register.source":"SPRING_CLOUD","content":"/"},"port":8086,"weight":1.0}

企业部署nacos注册中心部署的建议:

  1. 几个环境几个注册中心(开发环境1台机器1个注册中心,生产环境3台机器(集群)1个注册中心,测试环境1台机器1个注册中心),几个环境几个配置文件(比如passport-config-dev.yaml,passport-config-test.yaml,passport-config-prod.yaml)
  2. 1个配置中心,不同的ns(不建议)
  3. tomcat瓶颈优化的方法:1.横向扩展,增加容器的数量。2.代码优化修改并发连接数。

3.4.5 运行消费者consumer-feign-passport服务

3.4.5.1 运行消费者feign服务

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar consumer-feign-passport-0.0.1-SNAPSHOT.jar

3.4.5.2 服务注册

再次通过nacos页面查看服务注册情况
avator

3.4.5.3 访问消费者Feign服务接口

http://192.168.68.152:9092/v1/auth/login

{
msg: "demo passport api",
api: "/v1/auth/Feign controller",
type: "feign",
status: 200
}

http://192.168.68.152:9092/passport

{
msg: "后台服务passport-修改配置测试",
api: "/passport",
type: "feignPassport",
status: 200
}

3.4.6 运行消费者consumer-passport服务

3.4.6.1 运行消费者consumer-passport服务

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar consumer-passport-0.0.1-SNAPSHOT.jar

3.4.6.2 服务注册

通过nacos页面或者从服务日志可以看到注册成功

2020-08-27 10:41:27.177  INFO 21027 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, consumer-passport 192.168.68.152:9091 register finished

3.4.6.3 接口测试

http://192.168.68.152:9091/v1/auth/login

{
msg: "demo passport restTemplate /v1/auth/login api",
api: "{"msg":"demo passport api","api":"/v1/auth/consumer-passport","type":"passportProvider","status":200}",
type: "restTemplatePassport",
status: 200
}

http://192.168.68.152:9091/passport

{
msg: "demo passport restTemplate /passport api",
api: "{"msg":"后台服务passport-修改配置测试","api":"/passport","type":"autoNacosConfig","status":200}",
type: "restTemplatePassport",
status: 200
}

3.4.7 两种消费者调用的区别是什么

restTemplate和Feign的区别
在spring cloud 中有两种服务调用方式,一种是ribbon+restTemplate ,另一种是feign。相对来说,feign因为注解使用起来更简便。而restTemplate需要我们自定义一个RestTemplate,手动注入,并设置成LoadBalance。
内部调用:(内网相通)使用feign调用,调用方式为http://服务名/接口地址,比如:http://provider-passport/passport
跨地址/区域调用:(走外网调用)使用restTemplate调用,调用方式为http://服务IP地址/服务名称/接口地址,比如:http://192.168.68.152:8086/passport

我们在Java项目中调用接口有四种方式,分别是:
Httpclient
Okhttp
Httpurlconnection
RestTemplate

从消费者服务接口返回的内容与从passport提供者接口的内容一致,原理是访问消费者接口反向代理到提供者接口,获取返回内容。为什么要这么做的原因是如果后台有多个提供者的时候,消费客feign提供了负载均衡的作用。

3.4.8 运行网关服务

3.4.8.1 运行网关gateway服务

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar gateway-0.0.1-SNAPSHOT.jar

3.4.8.2 注册服务

同样的在nacos页面或者服务启动日志中可以看到服务注册成功信息

2020-08-27 11:19:37.475  INFO 22094 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, spring-cloud-gateway 192.168.68.152:9000 register finished

3.4.8.3 接口测试

通过gateway访问后台服务
通过consumer-feign-passport访问后台服务/v1/auth/login

正常请求feign调用
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login?token=1231

{
msg: "demo passport api",
api: "/v1/auth/Feign controller",
type: "feign",
status: 200
}

http://192.168.68.152:9000/consumer-feign-passport/passport?token=123123

{
msg: "后台服务passport-修改配置测试",
api: "/passport",
type: "feignPassport",
status: 200
}

正常请求restTemplate调用
http://192.168.68.152:9000/consumer-passport/v1/auth/login?token=122222

{
msg: "demo passport restTemplate /v1/auth/login api",
api: "{"msg":"demo passport api","api":"/v1/auth/consumer-passport","type":"passportProvider","status":200}",
type: "restTemplatePassport",
status: 200
}

http://192.168.68.152:9000/consumer-passport/passport?token=123123

{
msg: "demo passport restTemplate /passport api",
api: "{"msg":"后台服务passport-修改配置测试","api":"/passport","type":"autoNacosConfig","status":200}",
type: "restTemplatePassport",
status: 200
}

3.4.9 鉴权功能

我们在访问网关接口的时候,需要带token才能正常访问,否则会报非法请求
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login

{
code: 401,
cause: "Token字符串为空!",
message: "非法请求"
}

3.5 注册中心服务列表

服务必须存在与服务列表才能被调用
avator

3.6 微服务治理

3.6.1 服务熔断处理

在正常服务访问的情况下,后台服务不可用的情况下,或出现500的错误,返回客户端很不友好,并且接口之间的调试比较困难,因为不知道后台服务发生了什么错误。
将后台passport服务停掉模拟后台服务挂掉不可访问的状态,分别查看有服务熔断和没有服务熔断的接口返回
有服务熔断的返回:
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login?token=122222

{
msg: "feign 调用后台认证服务接口(/v1/auth/login)失败, 服务熔断处理.",
type: "feignFallBack",
status: 400
}

http://192.168.68.152:9000/consumer-feign-passport/passport?token=123123

{
msg: "调用后台认证接口(/passport)失败, 服务熔断处理.",
type: "feignFallBack",
status: 400
}

没有服务熔断的返回
http://192.168.68.152:9000/consumer-passport/v1/auth/login?token=122222

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Aug 27 14:13:04 CST 2020
There was an unexpected error (type=Internal Server Error, status=500).
No message available

3.6.2 服务熔断的实现方法

  1. 代码实现
  2. 集群实现(服务网格)

为什么会熔断?

  1. 服务调用超时
  2. 服务异常宕机
  3. 优雅处理异常

3.6.3 调用链

介绍

http://skywalking.apache.org/zh/blog/2019-03-29-introduction-of-skywalking-and-simple-practice.html

使用APM分析接口调用过程
注意:

  1. 采样率与损耗(默认是-1,每个3秒)
  2. 后台存储保存数量h2(5000条)

服务端启动

mkdir /root/apm && cd /root/apm
wget https://archive.apache.org/dist/skywalking/6.1.0/apache-skywalking-apm-6.1.0.tar.gz
tar zxvf apache-skywalking-apm-6.1.0.tar.gz
cd apache-skywalking-apm-bin/bin
sh startup.sh

正常启动以后通过页面访问http://192.168.68.152:8080/
用户名:admin
密码:admin

配置文件 application.yml

#启用ES的时候取消以下注释
#    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
#    indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2}
#    indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
#    bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000} # Execute the bulk every 2000 requests
#    bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20} # flush the bulk every 20mb
#    flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests
#    concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests
#    metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
#    segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}

#注释掉h2模式配置
  h2:
    driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}
    url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}
    user: ${SW_STORAGE_H2_USER:sa}
    metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}

服务端启动
拷贝agent目录到需要监测的设备上,本次为单机部署,故只需要将agent目录拷贝到指定目录即可,当然也可以不拷贝到指定路径,但是在启动服务的时候需要指定agent所在的绝对路径。

cp -r agent/ /root/springcloud/

启动provider passport服务

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=provide-passport \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar provider-passport-0.0.1-SNAPSHOT.jar

启动服务日志可以看到加载agent的信息

DEBUG 2020-08-27 16:34:03:616 main AgentPackagePath :  The beacon class location is jar:file:/root/springcloud/agent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class. 
INFO 2020-08-27 16:34:03:619 main SnifferConfigInitializer :  Config file found in /root/springcloud/agent/config/agent.config. 
...
2020-08-27 16:36:37.101  INFO 1080 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, provider-passport 192.168.68.152:8086 register finished

测试访问passport服务,查看skywalking是否可以获取到访问信息

for i in `seq 10000` ;do curl 192.168.68.152:8086/passport ;echo "";done

从页面查看信息
avator

同样的操作我们将消费者服务和网关服务也加入到skywalking的监测下
重新启动feign服务

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=consumer-feign-passport \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar consumer-feign-passport-0.0.1-SNAPSHOT.jar

重新启动restTemplate consumer-passport服务

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=consumer-passport \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar consumer-passport-0.0.1-SNAPSHOT.jar

重新启动gateway服务

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=gateway \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar gateway-0.0.1-SNAPSHOT.jar

将上述4个服务全部重启以后,再次在页面查看,可以看到skywalking已经监测到这4个服务。
avator

测试服务

  1. 对feien进行模拟访问测试
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login?token=122222
for i in `seq 10000` ;do curl http://192.168.68.152:9000/consumer-feign-passport/passport?token=123123 ;echo "";done
{"msg":"后台服务passport-修改配置测试","api":"/passport","type":"feignPassport","status":200}
{"code":403,"msg":"服务限流, 请立刻停止非法访问"}
{"code":403,"msg":"服务限流, 请立刻停止非法访问"}
{"code":403,"msg":"服务限流, 请立刻停止非法访问"}
...
  1. 对restTemplate passport进行模拟访问测试
for i in `seq 10000` ;do curl http://192.168.68.152:9000/consumer-passport/v1/auth/login?token=122222 ;echo "";done
for i in `seq 10000` ;do curl http://192.168.68.152:9000/consumer-passport/passport?token=123123 ;echo "";done 
{"msg":"demo passport restTemplate /v1/auth/login api","api":"{\"msg\":\"demo passport api\",\"api\":\"/v1/auth/consumer-passport\",\"type\":\"passportProvider\",\"status\":200}","type":"restTemplatePassport","status":200}
{"code":403,"msg":"服务限流, 请立刻停止非法访问"}
{"code":403,"msg":"服务限流, 请立刻停止非法访问"}
{"code":403,"msg":"服务限流, 请立刻停止非法访问"}
...

这里显示的内容是因为我们做了服务限流。
高并发系统中有三把利器用来保护系统:缓存、降级和限流。限流的目的是为了保护系统不被大量请求冲垮,通过限制请求的速度来保护系统。在电商的秒杀活动中,限流是必不可少的一个环节。

3.7 消费者调用

feign调用
avator

restTemplate调用
avator

3.7.1 什么是Feign

Feign是模板化的http客户端,可以帮助我们更快捷,优雅的调用http API(Rest)
Spring Cloud 对Feign进行了增强,使Feign支持Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便

3.7.2 为什么需要Feign

  • 前面已经提到在消费后台服务的时候已经存下RestTemplate服务,为什么还需要Feign?
  • Feign的目的是尽量的减少资源和代码来实现和HTTP API的连接(HTTP客户端封装)内网与外网调用。

3.7.3 什么是restTemplate

RestTemplate是Spring提供的额用于访问Rest服务的客户端,它提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。
当后台服务,比如新闻资讯服务启动以后,用户需要访问,那么需要通过consumer访问,在本实例中consumer独立为一个服务,在实际的应用开发阿忠,会与网关集成为一个整体的服务。

3.7.4 Frign与restTemplate对比

代码框架实现反向代理+负载均衡

比较类型 restTemplate+ribbon Feign(自带ribbon)
可读性,可维护性 欠佳(无法从URL直观了解这个远程调用过程) 极佳
开发体验 欠佳(拼接URL) 极佳(代码整洁)
风格一致性 一般(本地API调用和restTemplate调用的代码风格不同) 极佳(完全一致,不点开feign的接口根本不会察觉这是一个远程调用而非本地api调用)
性能 较好 中等(性能是restTemplate的50%左右,如果为feign配置连接池,性能可提升15%左右)
灵活性 极佳 中等(内置功能能满足大多数项目的需求)

3.8 网关调用过程

  • 把用户需要请求的URL地址通过路由的方式转发到后台的服务,同时也实现鉴权的功能。
    网关位置
    avator

3.8.1 网关调用restTemplate接口过程

  • 负载均衡根据调度算法调度到网关系统
  • 网关系统接收请求以后,如果消费者(restTemplate)返回正确,那么状态值为200,内容里面会包括provider返回的Json内容。
  • 消费者接收请求以后,如果服务提供者(Provider)返回正确,那么状态值为200.
    avator

3.8.2 网关调用Feign接口过程

  • 负载均衡根据调度算法调度到网关系统
  • 网关系统接收请求以后,如果消费者(feign)返回正确,那么状态值为200,内容里面会包括provider返回的Json内容。
  • 消费者接收请求以后,如果服务提供者(provider)返回正确,那么状态值为200.
    调用过程于restTemplate相同,只是feign多封装了一层http client。

3.9 小结

  • 所有服务注册到注册中心,并且每个服务可以展示多个实例
  • 注册实例分为:临时实例与永久实例
  • 网关:负责前台请求到后台的调用,起鉴权作用(配置文件路由/动态路由)
  • Provider:后台真正的服务提供者
  • Feign:网关通过此服务消费Provider
  • restTemplate:网关通过此服务消费Provider
  • 配置中心:在配置中心修改配置以后,可以实时通知到客户端,并且可以回滚配置到上一个版本。
posted @ 2020-08-30 14:54  Doc-Yu  阅读(2043)  评论(1编辑  收藏  举报