本博客主要是根据尚硅谷周阳老师课程学习而做的笔记
Github上全套资料(强烈推荐):https://github.com/leelovejava/cloud2020
IDEA中maven配置:
父工程pom文件中maven-project-info-reports-plugin爆红解决办法:添加一个依赖
https://blog.csdn.net/weixin_42957931/article/details/108901158
<packaging>pompackaging>
删除src
dependencyManagement和dependencies的区别
80端口的消费者只有Controller
Debug模式启动方便打断点
springcloud 返回的是xml,而不是json解决方案
https://blog.csdn.net/wobenyiwusuoyou/article/details/113837464
服务名称修改:eureka:instance:instance-id:
IP信息提示:eureka:instance:prefer-ip-address: true
7001
8001
https://github.com/Netflix/eureka/wiki
https://archive.apache.org/dist/zookeeper/
阿里云服务器启动Zookeeper
验证测试
启动Zookeeper客户端,发现服务注册进Zookeeper服务器
Zookeeper和Eureka
https://www.cnblogs.com/jis121/p/11019273.html
分布式系统的三个指标
1、Consistency 一致性
2、Availability 可用性
3、Partition tolerance 分区容错性
eureka基于AP,强调可用性
zookeeper基于CP,强调一致性
由于作为注册中心可用性的需求要高于一致性,所以eureka貌似要比zookeeper更合理一些
每一个微服务中都有eureka client,用于服务的注册于发现
(服务的注册:把自己注册到eureka server)
(服务的发现:从eureka server获取自己需要的服务列表)每一个微服务启动的时候,都需要去eureka server注册
当A服务需要调用B服务时,需要从eureka服务端获取B服务的服务列表,然后把列表缓存到本地,然后根据ribbon的客户端负载均衡规则,从服务列表中取到一个B服务,然后去调用此B服务
当A服务下次再此调用B服务时,如果发现本地已经存储了B的服务列表,就不需要再从eureka服务端获取B服务列表,直接根据ribbon的客户端负载均衡规则,从服务列表中取到一个B服务,然后去调用B服务微服务,默认每30秒,就会从eureka服务端获取一次最新的服务列表
如果某台微服务down机,或者添加了几台机器,此时eureka server会通知订阅他的客户端,并让客户端更新服务列表,而且还会通知其他eureka server更新此信息
心跳检测,微服务每30秒向eureka server发送心跳,
eureka server若90s之内都没有收到某个客户端的心跳,则认为此服务出了问题,会从注册的服务列表中将其删除,并通知订阅它的客户端更新服务列表,而且还会通知其他eureka server更新此信息eureka server保护机制,通过打卡开关,可以让eureka server处于保护状态,主要是用于某eureka sserver由于网络或其他原因,导致接收不到其他微服务的心跳,此时不能盲目的将其他微服务从服务列表中删除。
具体规则:如果一段时间内,85%的服务都没有发送心跳,则此server进入保护状态,此状态下,可以正常接受注册,可以正常提供查询服务,
但是不与其他server同步信息,也不会通知订阅它的客户端,这样就不会误杀其他微服务
zookeeper也可以作为注册中心,用于服务治理(zookeeper还有其他用途,例如:分布式事务锁等)
每启动一个微服务,就会去zk中注册一个临时子节点,
例如:5台订单服务,4台商品服务
(5台订单服务在zk中的订单目录下创建的5个临时节点)
(4台商品服务在zk中的商品目录下创建的4个临时接点)每当有一个服务down机,由于是临时接点,此节点会立即被删除,并通知订阅该服务的微服务更新服务列表
(zk上有watch,每当有节点更新,都会通知订阅该服务的微服务更新服务列表)每当有一个新的微服务注册进来,就会在对应的目录下创建临时子节点,并通知订阅该服务的微服务更新服务列表
(zk上有watch,每当有节点更新,都会通知订阅该服务的微服务更新服务列表)每个微服务30s向zk获取新的服务列表
临时还是持久结点
临时。一定时间内有就留下,否则清理。深刻理解AP和CP,高可用还是数据一致性。
订单服务注册进zookeeper
准备工作
中文文档参考手册
https://www.springcloud.cc/spring-cloud-consul.html
下载安装并运行
https://www.consul.io/downloads
服务提供者,服务消费者注册进Consul
测试
7001,7002 Eureka集群
8001,8001 支付集群
注:spring-cloud-starter-netflix-eureka-client自带了spring-cloud-starter-netflix-ribbon
关键字:
依赖:spring-cloud-starter-openfeign
使用:@FeignClient、@EnableFeignClients、@Autowired
注意事项:集成了ribbon,自带负载均衡效果
总结:
1)主要依赖:spring-cloud-starter-openfeign
如下,openfeign整合了netflix-ribbon,带有负载均衡功能。
2)在**
Spring cloud
应用中,当我们要使用feign
**客户端时,一般要做以下三件事情 :使用**注解
@EnableFeignClients
**启用feign
客户端;@SpringBootApplication @EnableFeignClients public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
使用注解
@FeignClient
定义feign
客户端 ;
示例 : 该例子定义了一个feign
客户端,将远程服务http://test-service/test/echo
映射为一个本地Java
方法调用。@FeignClient(name = "test-service", path = "/test") public interface TestService { @RequestMapping(value = "/echo", method = RequestMethod.GET) TestModel echo(@RequestParam("parameter") String parameter); }
使用注解
@Autowired
使用上面所定义feign
的客户端 ;@Autowired TestService testService; public void run() { // 这里的使用本地Java API的方式调用远程的Restful接口 TestModel dto = testService.echo("Hello,你好!"); log.info("echo : {}", dto); }
上面的三个步骤,前两个步骤可以理解为定义feign
客户端,第三步是使用所定义的feign
客户端。通过调试发现,上面第三步所注入的testService
是一个代理对象,如下所示 :
testService = {$Proxy66@5502}
"HardCodedTarget(type=TestService, name=test-service, url=http://test-service/test)"
h = {ReflectiveFeign$FeignInvocationHandler@6924}
target = {Target$HardCodedTarget@6930}
dispatch = {LinkedHashMap@6931} size = 1
0 = {LinkedHashMap$Entry@6948}
"public abstract xxx.model.TestModel xxx.service.TestService.echo(java.lang.String)"
该对象会代理客户端完成远程服务方法的调用,那么,该代理对象是如何生成的 ?这篇文章,我们通过源代码分析来回答这些问题。
参考博客地址:https://blog.csdn.net/andy_zhang2007/article/details/86680622
cloud-consumer-feign-order80的pom.xml
<parent>
<artifactId>cloud2020artifactId>
<groupId>com.atguigu.springcloudgroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>cloud-consumer-feign-order80artifactId>
<description>订单消费者之feigndescription>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId> org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>com.atguigu.springcloudgroupId>
<artifactId>cloud-api-commonsartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
cloud-consumer-feign-order80服务:接口PaymentFeignService
+ 注解@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
完成调用
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping(value = "payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id);
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout();
}
cloud-provider-payment8001支付模块8001服务:上面定义的会调用这里暴露的REST地址
测试:
启动eureka集群7001,7002
启动支付服务8001,8002
启动订单消费者之feign80
分析:
1)使用注解@FeignClient
定义feign
客户端 ;
2)使用**注解@EnableFeignClients
**启用feign
客户端;
3)使用注解@Autowired
使用上面所定义feign
的客户端 ;
4)控制台:
OpenFeign默认等待1秒钟,超过后报错
(1)应用场景
(2)开启配置
Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中HTTP请求的细节。也即对Feign接口的调用情况进行监控和输出。
https://www.cnblogs.com/monjeo/p/9330464.html
http://jmeter.apache.org/download_jmeter.cgi
设置语言为中文
https://www.cnblogs.com/ln-supergood/p/10773391.html
bin
目录下双击jmeter.bat
或者以管理员方式运行
服务降级一般放在80客户端。
80客户侧服务降级。
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
代码繁琐;统一和自定义的分开;
没有配置fallbackMethod
属性的用全局通用,配置了的精确打击。
Java工具包类库
https://hutool.cn/
理解服务熔断:
多次正确,然后慢慢正确,发现刚开始不满足条件,就算是正确的访问也不能进行;
下图:断路器打开
可参考第一季的课程
下半场、高级部分
Github上: https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
Spring上: https://spring.io/projects/spring-cloud-alibaba#overview
文档: https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
如果需要使用已发布的版本,在 dependencyManagement
中添加如下配置。然后在 dependencies
中添加自己所需使用的依赖即可使用。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>2.2.6.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
Github上
https://github.com/alibaba/Nacos
官方文档
https://nacos.io/zh-cn/
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_discovery
下载
https://github.com/alibaba/nacos/releases/tag/2.0.3
**下载:**https://github.com/alibaba/nacos/releases/tag/2.0.3
**mac下启动nacos,bin目录下终端执行命令:**sh startup.sh -m standalone
**访问:**http://localhost:8848/nacos
新建module:cloudalibaba-provider-payment9001
父pom
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>${spring.cloud.alibaba.version}version>
<type>pomtype>
<scope>importscope>
dependency>
子pom
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
yml
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
management:
endpoints:
web:
exposure:
include: '*'
主启动类添加注解 @EnableDiscoveryClient
启动服务,查看nacos
nacos自带负载均衡,参照9001新建9002:cloudalibaba-provider-payment9002
ribbon(1)负载均衡;(2)支持RestTemplate 远程调用
ApplicationContextConfig
@Configuration
public class ApplicationContextConfig
{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
OrderNacosController
@RestController
@Slf4j
public class OrderNacosController
{
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String serverURL;
@GetMapping(value = "/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id)
{
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
}
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
测试:
pom.xml
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
配置文件的加载是存在优先级顺序的,bootstrap.yml优先级高于application.yml
bootstrap.yml(重点的放在这里,全局)
# nacos配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服务注册中心地址
config:
server-addr: localhost:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
#group: DEV_GROUP
#namespace: 7d8f0f5a-6a53-4785-9686-dd460158e5d4
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# nacos-config-client-dev.yaml
# nacos-config-client-test.yaml ----> config.info
application.yml(自己的)
spring:
profiles:
active: dev # 表示开发环境
#active: test # 表示测试环境
#active: info
(1)DataID方案
指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension} # nacos-config-client-dev.yaml # nacos-config-client-test.yaml ----> config.info
spring:
profiles:
#active: dev # 表示开发环境
active: test # 表示测试环境
#active: info
(2)Group方案
得到结果如下:
(3)Namespace方案:命名空间–组--配置文件
https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
https://nacos.io/zh-cn/docs/deployment.html
默认Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。
为了解决这个问题,Nacos采用了 集中式存储的方式来支持集群化部署,目前只支持MySQL的存储。
nacos-server-1.1.4\nacos\conf目录下找到sql脚本
nacos-server-1.1.4\nacos\conf目录下找到application.properties