把SpringBoot看成一个学校
这个概念来自于
其中有些概念:
每个教研组就是一个微服务集群。
- SpringBoot:单体服务,快速创建项目,快速集成各种框架,易于测试,易于部署。
- Feign:微服务独立部署,通过相关协议通信。Feign 就是一个简单的申明式通信框架,基于 HTTP restful。
- Eureka:独立服务越来越多,服务实例也越来越多。服务治理便是必须的,Eureka 提供高可用的服务注册和服务发现功能。
注册中心Eureka
是存放教研组老师名单的地方。学生们想先访问这个注册中心获取教师名单,然后根据相应的负载方法去访问各自老师。不至于让集群中某一老师累死也不至于让某一老师闲死。
底下所涉及的组件(网关、熔断器等)也要注册到注册中心。
- Ribbon:Feign 只负责通信,Ribbon 提供客户端负载均衡,是系统优化的部分。
- Hystrix:微服务将带来服务间复杂的依赖关系,分布式和集群的复杂度也将带来许多难以预料的问题。为防止复杂网络和复杂系统某一点的问题导致整个系统的雪崩状态,便有了Hystrix,Hystrix 是 Spring Cloud 体系中优秀的断路器,可以在系统发生问题时进行服务降级,防止整体系统崩溃。
Hystrix熔断器,相当于学校的志愿者。
当一个教研组集体罢课后,学生找不到老师了,这些志愿者及时的告诉来访问的学生,相应的结果,异常信息等,免得大量的学生在学校等待,这些志愿者赶快把这些等待的学生疏散出去。
学生一直在学校等待,那其他需要学生的学校,也会等待学生,最后造成大面积的学校瘫痪。这里学生我们看成一个个请求。熔断器就是把某事故的蔓延即使熔断了。
- Zuul:统一网关,统一网关是以 Facade模式,对外提供友好的接口,微服务化之后,服务将越来越多,越来越复杂,为了降低外部系统调用的复杂度,统一网关就是常用解决方案。
Zuul网关就是学校的门卫。某些学生来找谁,负责指引(路由),并且通过一些非常简单的配置,达到阻拦一些人进入(身份验证),或者控制想学数学的人只能去数学教研组,不能去其他教研组(权限验证)。
- Config:服务划分越多,配置将越多,Spring cloud config 提供统一的配置管理。
- Sleuth:服务监控和治理。监控是复杂系统必需的基础设施。系统感知、问题发现、性能定位都需要监控的加持。
使用IDEA从零搭建SpringCloud
前面新建的步骤一致。只不过选择的版本是 jdk11.
提供注册服务
在运行时,需要了几个报错。
- 无效的源版本 7
- 无效的目标版本 11
因为在最初建项目的时候,选择的是1.6版本,但是有了log event的警告,说必须1.7+版本,所以切换到了11。
按照以下文章,通过调整project structure里面的配置。原则:language level< sdk的版本。
Java|无效的目标发行版:11解决方案
最终我的配置:
3. java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present
这个是因为JAXB-API是java ee的一部分,在jdk11中没有在默认的类路径中,所以需要单独配置。
可以采用
解决报错java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present 的方法,按照这里面的pom里面加依赖的方法进行配置。
运行成功的界面
客户端client 提供真正服务的角色的配置
步骤也是按照上面分享的那篇推送。但是在这之中遇到了很多问题。
- pom.xml记得和上面的一致,省得遇到与之前一样的问题。
只改下名字和推送中提到的client。 - 记得把resource文件夹右键设置为resource root 文件夹,不然会报错:
[main] DEBUG org.springframework.boot.context.logging.ClasspathLoggingApplicationListener - Application failed to start with classpath: unknown
当然有可能是因为父类版本号过高导致的。
解决方法如下:
Spring Cloud注册中心Eureka启动时出现: java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApp
- 记得把test的文件夹设置为普通文件夹,不然会读取AppTest.java,报里面的错。
- 记得application.yml里面别写错了,比如这里port后是有空格的
主要改了的就这几处。
开始的时候pom包总是不识别,修改了也没法自动import change,后来重新建了项目才可以。
折腾了挺久的,可算跑通了!
使用controller里面定义的,运行下~
页面中出现过这行红字
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER
这是因为Eureka有自我保护机制,在默认的情况下,如果Eureka server 在一定的时候内,没有接受到某个微服务的心跳,就会注销该实例,默认时间是90秒。
因为挂了太久了,目前只是测试状态,都重启一下就可以了。
网上也有很多解决办法。
搭建基于ribbon的客户端,用于消费服务
同理,也是主要按照推送的流程走的。
遇到的问题和处理方式和上面客户端client的相同。
好像在import 了 pom的change之后,自动会把test文件夹设成Test Source Root的文件夹,记得取消下。
三种调用方式:
第一种是直接调用:不经过注册中心那服务列表,直接访问的servicesupport
第二种:是根据服务名选择调用,如上图需要做如下注入
@Autowired
private LoadBalancerClient loadBalancerClient;
如上图代码中第二种调用方法的代码所示。
用服务名去注册中心获取服务列表,当前客户端底层会做随机算法的选取获得服务并访问。
第三种需要一个@Bean的注解自动注入并直接调用restTemplate对象调用服务。底层调用模式与第二种调用方式一样。如下:
@Configuration
public class Beans {
//管理简单对象
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
但是遇到了如下问题
***************************
APPLICATION FAILED TO START
***************************
Description:
Field restTemplate in com.jack.springcloud.controller.DeptController_Consumer required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
在启动类(application类)中添加如下代码
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(180000);//单位为ms
factory.setConnectTimeout(5000);//单位为ms
return factory;
}
之后便可正常启动了
Eureka server的高可用配置
这个只是进行配置而已,按照推送来就可以
server的yml如下所示:
# 指定当前eureka客户端的注册地址,也就是eureka服务的提供方,当前配置的服务的注册服务方
eureka:
client:
service-url:
defaultZone: http://localhost:8699/eureka,http://localhost:8698/eureka #配置另外两台的端口
register-with-eureka: false #自身 不再向eureka注册
fetch-registry: false #启动时禁用client的注册
#指定应用名称
spring:
application:
name: eureka-server