首页 > 编程语言 > 详细

SpringCloud 学习笔记

时间:2019-02-11 22:42:37      阅读:221      评论:0      收藏:0      [点我收藏+]

学习资源:https://ke.qq.com/course/280057

 

知识体系分为一下几点:

1)使用Eureka搭建注册中心,包括

服务生产者、服务消费者(也称服务注册与发现);

Zookeeper和Consul注册中心的使用;

搭建Eureka集群

会员服务实现负载均衡ribbon

 

2)搭建依赖聚合项目,仿照大公司真实环境,包括

从这里可以理解微服务的架构模式了,讲解了feign客户端的缺点以及怎么规避他

 

3)搭建分布式配置文件中心,包括

手动刷新

服务雪崩效应,使用Hystrix解决高并发问题,讲解服务降级、服务熔断、服务隔离、断路器

 

4)搭建网关,包括

动态网关搭建--就是整合了分布式配置文件中心

Nginx+zuul实现网关集群

 

5)Swagger生成接口文档、SpringCloud bus消息总线、消息驱动、SpringCloud Stream

 

 

v1.2.7
spring-cloud-starter-eureka-server

v2.0.0
spring-cloud-starter-netflix-eureka-server

 

必须要配置spring的仓库地址,否则jar包下载不下来,就蚂蚁课堂最后那句话

 

@EnableEurekaServer注解表示开启EurekaServer服务,开启注册中心
@EnableEurekaClient注解表示将当前服务注册到Eureka上

 

以别名方式运行必须调用依赖ribbon负载均衡器 @LoadBalanced,否则会抛出java.net.UnknownHostException异常

集群时注册中心的服务名称要相同

 

 

 


Eureka集群时,每个注册中心上面都会有相关服务,但是蚂蚁课堂上面演示为只有第一个注册中心上面有服务,当第一个注册中心关闭后,程序会在30秒后默认将服务放在第二个注册中心上;

 

Eureka的自我保护机制论述:默认情况下EurekaClient会定时向EurekaServer端发送心跳包,如果EurekaServer在一定的时间内没有收到EurekaClient发送的心跳包,便会直接从服务注册列表中剔除该服务(默认90秒内)。
但是如果在短时间内丢失了大量的服务实例心跳,这时候EurekaServer就会开启自我保护机制,不会去剔除该服务。

为什么不会剔除呢?
为了防止EurekaClient是可以正常访问的,但是只是EurekaClient与EurekaServer网络访问不通,防止误剔除。

应该在什么环境下开启自我保护机制?
建议在本地环境禁止自我保护机制,在生产环境开启自我保护机制。
因为本地测试可能需要频繁的开启/关闭某些服务。

关于自我保护机制的一些问题:
最好的体现就是:memberApp负载均衡,先开8400端口,关闭之后再开8401端口,此时你会发现注册中心上始终都有8400端口的服务;而你关闭自我保护机制后,再重复以上步骤,这个8400端口会迅速消失;
--》idea升级为2018.2后,这个memberApp负载均衡写不了了,改变端口重启服务时idea提示该项目为单例模式,必须先关闭后重启。【已解决】

  server:
    ###测试时关闭自我保护机制,保证不可用服务及时剔除
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000

 

 

 

导入atom主题后,idea项目报错,重构时遇到以下异常:
Error:Cannot run program "C:\Program Files\Java\jdk1.8.0_92\bin\java" (in directory "C:\Users\Administrator\.IntelliJIdea2017.1\system\compile-server"): CreateProcess error=2, 系统找不到指定的文件。
--》当初只顾看Event Logs了,没有检查SDK是否配置;
--》重装后,SDK没有配置,也出现该问题,配置好之后就没事了;

 

zookeeper 分布式协调工具,可以实现注册中心
所有实现方式基本一致,只需要先开启zookeeper的服务端,然后再打开客户端jar包即可。

consul也一样,打开cmd窗口,到指定目录,然后输入一串命令即可。

两者都是通过@EnableDiscoveryClient注解实现注册;

zookeeper一开始连接失败,后面又可以了,可能时我多启动了几次吧,我先用zkcli.cmd测试了一下,然后再打开这个工具用127.0.0.1连接的,后面测试localhost也可以了

zookeeper和consul都没有自我保护机制

@EnableDiscoveryClient,如果服务使用consul、zookeeper,就需要用这个注解向注册中心注册服务

 

 

DiscoveryClient可以获取服务的一些信息

 

负载均衡算法:总请求数量%服务器数量得到实际下表服务器位置

不建议使用 synchronized,使用原子计数器,应为线程安全,效率非常高,使用cas无锁机制

 

Ribbon本地负载均衡,原理:在调用接口时,会在注册中心上获取注册信息服务列表,获取到之后,缓存在jvm本地,让你使用本地实现rpc远程调用技术进行调用,由客户端实现负载均衡;

Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后有nginx实现转发请求,所以nginx由服务器端实现负载均衡。

应用场景:
ribbon本地负载均衡适合在微服务rpc远程调用,比如dubbo、springcloud;
nginx服务器负载均衡适合于针对与服务器端,比如tomcat、jetty;

 

Feign是一个声明式的Http客户端调用工具,采用接口+注解方式实现,易读性比较强

 


consul启动步骤:
cmd到consul.exe放置目录,输入命令 consul agent -dev
输入网址 http://localhost:8500
就可以了

 

consul似乎有点卡顿,当我启动一个注册服务后,刷新consul的页面,他没有反应,我在consul的cmd窗口中按了下回车就有反应了;【已解决,这是我鼠标点击了窗口】

 

由于考虑到后续的服务降级,比如fallback属性需要指定类路径,而类路径是是订单服务,而不是会员服务;
--》服务降级取决于调用者,而不是被调用者;

 

依赖聚合项目
实体类最好放在接口项目中

Modifier ‘public‘ is redundant for interface methods less... (Ctrl+F1)
Inspection info: Reports any redundant modifiers on interfaces or interface components.

接口不能加@RestController,因为接口不能被实例化

引入依赖时,版本号必须得加

依赖聚合项目想要达到的目的:避免传统的feign缺点,在order中建立一个类写着跟memberController一样的内容,这样很冗余;所以就采用maven子父工程,这样一来,在order中建立的feign类只需要继承memberService就可以了。
--》注意这个项目分了Service,ServiceImpl,但是没有Controller,这个MemberService完全和之前项目的feign类内容一样。

 

 

 

服务雪崩效应
解释:默认情况下tomcat只有一个线程池去处理客户端发送的所有服务请求,这样的话在高并发情况下,如果客户端所有的请求堆积到同一个服务接口上,就会产生tomcat的所有线程去处理该服务接口,可能会导致其他服务接口访问延迟;

Hystrix,别名“豪猪”

Hystrix服务保护框架,在微服务中Hystrix为我们解决了哪些事情?
1 断路器
2 服务降级
3 服务熔断
4 服务隔离机制
5 服务雪崩效应
--》连环雪崩效应,如果比较严重的话,可能会导致整个微服务接口无法访问,所有服务都会瘫痪


解决服务雪崩效应原理:
1)服务降级
在高并发情况下,防止用户一直等待,使用服务降级方式(返回一个友好的提示直接给客户端,不会去处理请求,调用fallback本地方法),目的是为了用户体验
比如秒杀--当前请求人数过多,请稍后重试。(在tomcat中没有线程进行处理客户端请求的时候,不应该让用户一直转圈等待。)

2)服务熔断
例如保险丝,服务熔断的目的是为了保护服务,在高并发情况下,如果请求达到了一定的极限(可以自己设置阈值),如果流量超出了设置的阈值,会自动开启保护服务功能,使用服务降级方式返回一个友好的提示。
熔断机制和服务降级一起使用。
默认阈值为10个

3)服务隔离
采用线程池隔离,每个服务接口都有自己独立的线程池,每个线程池互不影响;
缺点:CPU占用率非常高。
不是所有的接口都要去采用线程池隔离,只有核心关键接口才需要

 

 

当一个服务被大量线程数访问时,另外一个服务能访问,但是却跳到了fallback方法中,这是因为Hystrix需要设置禁止超时时间;
@HystrixCommand注解默认开启了线程池隔离,服务降级,服务熔断

feign超时时间需要设置,否则会报错
java.net.SocketTimeoutException: Read timed out
--》我设置这一步时,在yml文件中添加相关配置,idea没有给出相应提示,本来还有点怀疑,但是运行之后竟然成功
了。


Hystrix有两种方式实现:一种是注解,一种是接口

java.util.concurrent.TimeoutException: null

这个Hystrix的超时时间会影响所有的接口,不是只针对@HystrixCommand注解的接口

如果调用其他接口超时的时候(默认是1秒时间),默认情况下业务逻辑是可以正常执行的,但是为了避免客户端等待,会直接执行服务降级方法。

java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN

 

 


如果配置文件全部放在resources目录下,管理起来非常复杂,所以采用分布式配置中心,放在git上

分布式配置中心
产生背景:在微服务中如果使用传统的方式管理配置文件,配置文件管理器非常复杂;
如果生产环境配置文件,可能需要发生改变的时候,重新打war,重新读取配置信息在jvm内存中;

什么是分布式配置中心:在微服务中使用同一个服务器管理所有服务配置文件信息,能够实现后台可管理,当服务器正在运行时,如果配置文件需要发生改变,可以实现不需要重启服务器实时更改配置文件信息。


分布式配置中心框架
阿波罗 携程的,有图形界面可管理配置文件信息,配置文件信息存放在数据库里面
SpringCoud Config 没有后台可管理分布式配置中心,配置文件信息存放在版本控制器里面(git/svn)
Zookeeper 持久节点+事件通知

搭建分布式配置中心所需要的组件:
1)web管理系统,后台可以使用图形界面管理配置文件
2)存放分布式配置文件的服务器(持久存储服务器),使用版本控制器
3)ConfigServer缓存配置文件服务器(临时缓存存放)
4)ConfigClient读取ConfigServer配置文件信息

 

 

 


1、git环境上文件夹以项目进行区分
member_config 会员服务配置文件
order_config 订单服务配置文件

2、公司项目中环境是如何区分
dev 开发环境
sit 测试环境
pre 预发布环境
prd 准生产环境

 

 


客户端的命名要和git上的服务名称一样,因为系统会议该命名为前缀去git上面搜索
配置文件命名规则:服务名称-环境.properties

 


config-server搭建好后,sit文件访问有内容,而prd访问没内容
--》可能是gitee的问题,删掉重新建一个就可以访问了;这里不能访问,后面的config-client也是不能访问的;

注意这个config-client的yml文件为prd
在config-client启动后,如果某个配置文件不存在(服务名/环境名错误),那么程序就会立马报错;

 

1、默认情况下不能及时的获取实时变更的配置文件信息
2、springcloud分布式配置中心 可以采用手动刷新或者自动刷新
手动刷新---需要人工调用接口,读取最新配置文件(监控中心)--建议使用
自动刷新---消息总线进行实时通知,springbus --不建议使用,更加消耗性能
两者都不需要重启服务器

要实现手动刷新,要用到actuator,在yml中配置,然后在Controller上面加上@RefreshScope注解;
还要手动发一个post请求:http://localhost:9300/actuator/refresh
--》一般来说,会将配置信息放在一个类上面,把@RefreshScope注解放在那个类上面就可以了;肯定不会在所有Controller上面加注解的;

 


码云写中文,获取时会乱码

Hystrix的注解方式业务代码和return 调用的方法是属于同一个线程的
而第二种方式,业务代码和return调用的方法是两个线程,并且属于不同线程池

第一种方式比较冗余,所以最好采用第二种方式

 


接口产生背景:
在面向服务架构和微服务背景下产生,目的都是为了解耦。
rpc远程调用中产生的

接口如何进行分类
开放接口:其他机构合作伙伴进行调用(必须在外网访问),如蚂蚁开放平台、微信公众号开发
需要通过appid+appsocet生成accessToken进行通讯。
对接支付开发、微信开发会用到。
这样设计的目的:可以授权一些接口权限,OAuth2.0协议方式,第三方联合登陆。

内部接口
一般只能在局域网中进行访问,服务与服务调用之间关系都在同一个微服务中。
目的是为了保证安全问题。

面试问答,现在让你去设计一套公司项目的接口,你会如何设计?
考虑:接口权限(开放接口|内部接口),开放接口要遵循OAuth2.0协议,内部接口要经过网关才能访问;
考虑幂等性、安全性(https)--采用双向加密、防止篡改数据(验证签名)、使用网关拦截接口,实现黑名单和白名单、 接口使用http协议+json格式,采用restful风格,目的是为了跨平台。
然后需要考虑高并发,需要对接口服务实现保护,进行服务降级、熔断、隔离之类,最后使用统一API管理平台api swagger

 

 


网关的作用:
网关可以拦截客户端所有请求,对该请求进行权限控制,负载均衡、日志管理、接口调用监控等操作。

过滤器与网关的区别是什么?
过滤器适合于单个tomcat服务器进行拦截请求
网关是拦截整个微服务所有请求

网关分为内网网关和外网网关,外网网关是针对于开放平台接口

反向代理的目的是隐藏真实ip地址

 


Nginx与Zuul区别
相同点:
Zuul和Nginx都可以实现负载均衡、反向代理、过滤请求、实现网关效果。
不同点:
Nginx采用C语言编写
Zuul采用java语言编写

Zuul负载均衡实现:采用ribbon+eureka实现本地负载均衡
Nginx负载均衡实现:采用服务器端实现负载均衡
Nginx比Zuul功能会更加强大,因为Nginx可以整合一些脚本语言(Nginx+Lua)
Nginx适合于服务器端负载均衡,也可以实现网关
Zuul适合微服务中实现网关,而且使用技术是java语言

最好建议nginx+zuul实现网关
nginx用作实现反向代理
zuul对微服务实现网关拦截

 


网关框架
Kong Kong是基于nginx+lua进行二次开发的方案

使用网关后,不能直接输入真实地址访问会员服务/订单服务,而是运用了反向代理机制,输入网关地址+服务名称,程序会自动转发到对应的会员服务/订单服务;
f12是捕捉不到真实地址的

公司的token一般放在请求头里面,很少以?号传参

配置完网关后,配置的服务一开始没启动,是不会报错的;
只是当你输入地址后,如果这个地址和你配置的相同,而该服务没有启动,才会报错;

zuul配置能够使用config实现实时更新,还是得手动刷新

这个手动刷新有点问题:当你在配置文件上面添加内容,他可以生效;但是当你删减内容,他不会生效,可能是有缓存;

 

 

这个网关我原本用的application.yml,结果一直搜索不到config服务器,一直搜的8888端口;我比对了一下,之前那个config-client就是yml名称为bootstrap,所有我就也改成了bootstrap,结果就可以了,不晓得是什么原因。
---但是蚂蚁课堂的用的application.yml却可以成功
---》
原因如下:
首先如果你在Controller中使用@Value("${fileName}")去加载git上的配置文件属性,当你用的application.xml时,启动就会报错;
结合以上两个现象得出结论:
1)由于添加了config-client依赖,并且你是application.xml,他的加载顺序比较慢,这是还没有读取到yml配置中的config-server名称,所以这个客户端就会搜索到一个虚拟的config-server,如下
Fetching config from server at: http://localhost:8888
而如果你用的bootstrap.xml,他的执行顺序比较快,所以就加载了yml文件,找到了真正的config-server地址
Fetching config from server at: http://LIJ55MM21H39YNQ:9200/

 

 


网关集群思路
客户端发送请求统计到Nginx上,再使用Nginx实现反向代理和负载均衡,采用轮询机制转发到网关上。
--》集群时如果用谷歌浏览器可能负载均衡效果显示不出来(需要配置参数),可以用火狐浏览器。但是我的谷歌浏览器却是可以的


网关的作用重述:
1)网关对所有服务会话进行拦截
2)网关安全控制,统一异常处理,XXS、SQL注入
3)权限控制,黑名单和白名单、性能监控、日志打印

 

 

 

使用windows版本的nginx启动时遇到(1113: No mapping for the Unicode character exists in the target multi-byte code page)这个错误
后来查阅资料发现是因为解压的路径里面包含有中文的缘故,只要把解压后的文件剪切到没有包含中文的目录即可解决问题

nginx一闪而过是正常的,判断是否开启,可以再任务管理器中查看是否有相关进程,如果没有就看日志输出,看是什么错误;

后续的Swagger、SpringCloud bus消息总线、SpringCloud消息驱动、SpringCloudStream我没有实践,关于消息驱动这一块我没看完,因为对于消息队列很不熟悉,有点听不懂;

 

 

问题:

注册中心关闭后,消费者还可以访问生产者?

zookeeper的临时节点和持久节点?

不建议使用 synchronized,使用原子计数器,应为线程安全,效率非常高,使用cas无锁机制?

consul上面的order不能访问member,蚂蚁课堂没有演示该场景?

蚂蚁课堂说Controller不要,直接改成Service;

继承后,方法注解是否一并被继承

同一个父/祖父工程下的项目,是不是可以相互进行依赖

xxl-job

 

备注:

E:\Download Files\ChromeDownload\springcloud资料下载\cloud\文档\11-18\上课代码\springcloud-2.0-eureka-server

D:\Computer Files\File_Storage_Address\Software_Data_Center\IdeaProjects

 

 

SpringCloud 学习笔记

原文:https://www.cnblogs.com/syjp/p/10363466.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!