因为加了不少优秀的知识星球,结交了更多的小伙伴,加了更多的群,每每在自我介绍的时候,都说自己是Android & Java攻城狮。
然鹅,有的小伙伴就来问了,你是搞Java的,那对Spring很熟悉咯?哦,大佬,Spring Cloud搞的怎么样了呢?我是微服务的开发,期待和你一起交流……这样来交流的朋友,我觉得自己很惭愧。
其实我是个中间件开发。我目前的技术栈是基于Netty、WebSocket在开发一款聊天服务器,所以这些我并不会啊。可是,也确实一直在圈内听到微服务这个字眼,知道很多公司已经在使用微服务用的很熟悉了,我要是再跟不上,那就真的得跪了。所以,给自己定了一个小目标,必须开启微服务之旅,哪怕只是练手。
小编参考的书籍是【猿天地】的号主,尹吉欢撰写的《Spring Cloud微服务》。这里还得感谢【明哥的江湖】号主明哥的赠书,也算是给我节省了买书的饭钱。
初次接触Spring Cloud,一看到各种版本,刚开始有点懵逼。给大家看下最新的Spring Cloud的版本是什么样子的。
这些版本名称的命名方式采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序。比如最早的Release版本:Angel,第二个Release版本:Brixton,然后是Camden、Dalston、Edgware、Finchley,Gerrnwich,现在最新的快照版本是Hoxton了。
SNAPSHOT:快照版本,随时可能修改
SR:Service Release,SR1表示第一个正式版本,一般同时标注GA:(GenerallyAvailable),表示稳定版本。
所以小编在这里选择了最新的Greenwich SR1版本。相对应的,Spring Boot在官网里,也会有介绍。Greenwich对应的就是2.1.x,因为小编是初学,所以也用了最新的版本,2.1.5 Release。版本选择很重要,版本选择很重要,版本选择很重要,重要的事情说三遍,版本选择如何,决定你之后编程的路好不好走。
因为选择了最新的版本,很多资料也就不怎么存在了,好在Spring Cloud 2.x版本通过搜索还是能找到一部分资料的,而且多亏有尹大的在线帮助,在学习的过程中也是避开了一部分困难。
这部分我叫他踩坑之旅,就是因为在实践过程中,遇到了不少问题,都是一步一步调试过来的,确实很艰辛。想必也是大家比较想看的部分,马上呈上来。
导入Spring Boot 2.1.5 版本就开始报错了
在pom.xml文件的第一个行,总是报“Maven Configuration Problem,Unknwon”,很无语有木有,你报错就报错呗,还给我来了一个unkown,让我无从下手。
这次的答案,是在Stackoverflow上找到了答案,说明如下
照着这个步骤,我所在的环境是解决了,如果你有类似的报错,以及还没有完美解决,可以互相交流交流。
导入的dependency遇到missing
这里有一类问题,小编刚开始入门,学习的是注册,那就得用到eureka组件。书中用的版本是Dalston版本,Sping boot用了1.5.x的,所以导入的依赖就是
12 org.springframework.cloud 3 spring-cloud-starter-eureka 4 <dependency>
2 <groupId>org.springframework.cloudgroupId>
3 <artifactId>spring-cloud-starter-eurekaartifactId>
4dependency>
但是,这个在升级的版本里就报错了,硬是没找到依赖。后面还有好几个需要用到spring-cloud-starter-xxx的地方,都会报相同的错误。比如
1spring-cloud-starter-hystrix <artifactId>spring-cloud-starter-hystrixartifactId>
也是如此。遇到此类情况,我们需要更换下地址,得把netflix这个重要的加上,加这个的原因,不仅仅是为了升级,我想也是Netflix公司为了更好的宣传自家的产品吧。解决方案就是
1spring-cloud-starter-netflix-eureka-server 2spring-cloud-starter-netflix-hystrix <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
2<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
基于第二条,也有例外的情形
原本以为这个套路很深,都加netflix就搞定了,但是遇到feign组件的是,这个不奏效了,摊手。
1spring-cloud-starter-feign <artifactId>spring-cloud-starter-feignartifactId>
加了netflix也不奏效,好吧,继续努力寻找答案去呗。因为这里找的资料比较多了,来源有点不清晰,最后的结果就是将这个依赖改成如下即可
1spring-cloud-starter-openfeign <artifactId>spring-cloud-starter-openfeignartifactId>
eureka开启验证,登录的用户名和密码始终错误
eureka开启验证之后,需要在配置文件里把用户名和密码配置上去,否则就会有默认的用户名“user”,以及在控制台自动生成一串密码供我们登录。
小编刚开始的配置,还是按照书上写的
1用户名2security.user.name=xxx3密码4security.user.password=xxx
2security.user.name=xxx
3密码
4security.user.password=xxx
结果启动的时候,看到控制台上还是生成了一串密码,并且输入了自己在配置文件中的用户名和密码,都是进不了注册后台的。这个时候,就彻底懵逼了,代码也看不到错误,配置文件错误的话,也看不到啥信息,如何是好。
最后,小编在CSDN上找到一篇名为《security.basic.enabled 配置过时或不可用》的文章里,看到了,2.x版本的属性配置,是需要加前缀spring的,也就是如下:
1spring.security.user.name=xxx2spring.security.user.password=xxx
2spring.security.user.password=xxx
eureka开启关闭认证方式
继续上一个问题的补充,在开启验证的时候,老版本是需要在配置文件里将eureka开关打开,也就是用
1security.basic.enabled=truetrue
只不过当小编把值改成false的时候,还是出现需要用户名和密码登录的验证框。在没看上一篇的解决方案之前,也确实有点不知所措,后来看了CSDN的那篇解决方案下面就有了答案。
结合其他地方的资料,总结起来就是:旧版本的Spring Security的依赖是可以在配置文件内容直接通security.basic.enabled参数进行开启basic认证,不过目前版本已经被废除,既然这种方式不可行,那我们就使用另外一种方式进行配置,通过继承WebSecurityConfigurerAdapter安全配置类来完成开启认证权限
1@EnableWebSecurity 2 static class WebSecurityConfig extends WebSecurityConfigurerAdapter { 3 @Override 4 protected void configure(HttpSecurity http) throws Exception { 5 http.csrf().disable().authorizeRequests() 6 .anyRequest() 7 .authenticated() 8 .and() 9 .httpBasic();10 }11 }@EnableWebSecurity
2 static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
3 @Override
4 protected void configure(HttpSecurity http) throws Exception {
5 http.csrf().disable().authorizeRequests()
6 .anyRequest()
7 .authenticated()
8 .and()
9 .httpBasic();
10 }
11 }
代码在编译阶段报错
这里小编遇到了两次,解决方式都是同样的。第一个是遇到Caused by:java.lang.ClassNotFoundException:com.google.common.collect.Lists。
在这里,网上有朋友就说了,如果在查阅完代码,发现没有问题的时候,那么有一种可能是你的此依赖包并没有下载完整。记住这个重点哦,小编就是因为第一次遇到的时候没在意,第二次还碰到了。
第一次出现的时候,小编直接看到就去删了maven的依赖,在这个错误下删除的路径是“/repository/com/google/guava/guava” ,然后就可以编译成功,并执行完成了。到第二次,我竟然又踩坑。
第二次的错误是一堆堆栈报错
看到小编划的红线了没,其实这个时候,已经很明确告诉我们是没找到包下的类,但是小编一开始并没有仔细看这个错,而是去搜索引擎上查找答案。这次遇到麻烦了,全网就一篇类似的文章,还各种中文简体、繁体、英文大肆的写,可能对当时的场景有用,对我们这个场景没啥帮助。
这次,因为没有仔细吸取上次的教训,小编花了3小时来排查问题,等到夜深人静的时候,小编又在报错看了又看,看了又看,把眼泪都看出来了。好的,最终决定去删除一下依赖包。
就在小编没报任何希望的时候,代码竟然过了,跑的不亦乐乎。写程序的你,能感受到那份兴奋吧。噢,如果你是大拿,那可能不会这么强烈,不过我是达到高潮了,这个必须高潮。在此之前,小编在知识星球上求助了,贴子刚发完,没想到啊没想到,看来有时候不逼自己一把,还真不知道自己潜力有多少。
Feign整合Hystrix又有错
错误真的是一环扣一环,每次学习完这个组件,马上进入下一个组件,开始功能整合的时候,Bug总是不停地向你招手,招手,要是小姐姐也就算了,可惜她不是呀。
在微服务架构中,Hystrix除了实现容错外,还提供了实时监控功能。在服务调用时,Hystrix会实时累积关于HystrixCommand的执行信息,比如每秒的请求数、成功数等。
当你启动了Hystrix,并且输入
http://localhost:8082/hystrix.stream这个地址的时候,原本我们期望看到的结果是能在页面中看到"ping"请求,以及请求的""data"数据,但是这次小编并没有看到。
看过前面遇到的这么多错,想必你也知道,这是因为新版本引起了的吧。这个还好说,把地址改成
(http://localhost:8082/actuator/hystrix.stream)
Actuator 2.x 以后endpoints全部在/actuator下,可以通过management.endpoints.web.base-path修改)
1management.endpoints.web.exposure.include=*
拦路虎再次出现,这次是Zuul
这本书的第一阶段就快学完了,小编甚是兴奋。本以为到最后了,该解决的问题基本都差不多了,该遇到的问题基本上也都遇到过了,呵呵,太年轻。
Zuul在自定义异常上换包名了。其中其中的ErrorAttributes,ErrorController,DefaultErrorAttributes在SpringBoot 2.x的时候都转到org.springframework.boot.web.servlet.error包中,原本是在org.springframework.boot.autoconfigure.web上的。
所以,原先使用的
1public Object errorApiHandler(HttpServletRequest request,boolean includeStackTrace) {2 RequestAttributes requestAttributes = new ServletRequestAttributes(request);3 Map attr = this.errorAttributes.getErrorAttributes((WebRequest)requestAttributes,includeStackTrace);4 ......5}public Object errorApiHandler(HttpServletRequest request,boolean includeStackTrace) {
2 RequestAttributes requestAttributes = new ServletRequestAttributes(request);
3 Map attr = this.errorAttributes.getErrorAttributes((WebRequest)requestAttributes,includeStackTrace);
4 ......
5}
就不能这么使用了,得把代码换成
1public Object errorApiHandler(HttpServletRequest request,boolean includeStackTrace) {2 WebRequest webRequest=new ServletWebRequest(request);3 Map attr = this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace);4 ......5}public Object errorApiHandler(HttpServletRequest request,boolean includeStackTrace) {
2 WebRequest webRequest=new ServletWebRequest(request);
3 Map attr = this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace);
4 ......
5}
至此,在学完《Spring Cloud微服务》的准备篇和基础篇之后,小编算是见识到了微服务的厉害。
也因为小编选择了新版本,有部分问题出现的时候并不能第一时间在网上找到解决方案,这就让自己对微服务的研究更加深入。其实一开始,小编连版本都不知道怎么选,都不知道刚开始接触的时候,是哪来的自信。
微服务社区现在已经很强大了,小编在找资料的过程中,很多疑问都是通过Netflix在GitHub上的issue找到的答案,还有尹大的GitHub上也给了我很大的帮助。这些都是宝贵的经验所在。以及尹大的【猿天地】知识星球,在那里提出问题,尹大说了,我就是在最专业的星球里,让我不能畏首畏尾,尽管放马过去。
除了需要好好使用搜索引擎之外,小编最大的感触就是要看官方文档,看官方文档,看官方文档,很多文章肯定也是根据官方文档得出的答案,在使用过程中,小编有部分问题也是在那里解决的。这次学习,单独整理了一个微服务的书签,每天看着里面的数量在增加,问题在减少,帮我一步步完成了小白到入门的进化,很是欣慰。
学习是艰辛的,尤其是遇到困扰了3小时的问题,还一筹莫展的时候,都想过放弃。但是,放弃了,我就不能在其他地方更好地给自己贴上Java开发的标签了,也不能更好地和朋友们做技术交流。想到这里,我就会去泡杯咖啡,洗把脸,继续回来努力着,坚持着,奋斗着,或许这就是技术的魅力所在吧。
爱生活,爱学习,爱感悟,爱挨踢