springCloud使用(前半部)
Posted strandtrack
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springCloud使用(前半部)相关的知识,希望对你有一定的参考价值。
知识导读:
- 认识RestTemplate,并且使用它发送请求
- 了解SpringCloud,知道它的作用
- 熟悉Eureka注册中心
- 知道Ribbon负载均衡
- 使用Hystrix熔断器
1.系统架构的演变
随着互联网的发展,网站应用的规模不断扩大。需求的激增,带来的是技术上的压力。系统架构也因此也不断的演
进、升级、迭代。从单一应用,到垂直拆分,到分布式服务,到SOA,以及现在火热的微服务架构。是什么导致了
架构的不断演变,哪些需求需要我们来不断地更新架构,这些架构又是如何解决这些问题的。
1.1 集中式架构
在网站需求量较小的时候,我们使用单机式的架构就足以满足访问的需求,只需要一个应用,将所有功能部署在一起,
达到减少成本的目的。这个的优点就是开发速度快,维护成本低等。
1.2 垂直拆分
当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆
分成不同的模块,这样做的好处是实现了流量分担解决并发问题,而且可以分模块的进行开发和优化。
1.3分布式服务
当访问量进一步增大,这时候应用越来越多,应用之间交互不可以避免,将核心业务抽取出来,形成一个服务中心。
使得应用能够更快的响应。优点是提高了代码的复用等。
1.4soa架构
SOA(Service Oriented Architecture)面向服务的架构:它是一种设计方法,其中包含多个服务, 服务之间通过相
互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中。各个服务之间 通过网络调用。
1.5微服务架构
微服务架构是使用一套小服务来开发单个应用的方式或途径,每个服务基于单一业务能力构建,运行在自己的进程
中,并使用轻量级机制通信,通常是HTTP API,并能够通过自动化部署机制来独立部署。这些服务可以使用不同的
编程语言实现,以及不同数据存储技术,并保持最低限度的集中式管理。
2服务调用方式
微服务现在已经慢慢地成为国内互联网公司的主流和趋势,而微服务是分布式的,所以需要远程的服务调用。
主要分为两种,一种是RPC,一种是http。
RPC的代表框架是Dubbo,这个是阿里的一个框架,用起来效率很高。
http的代表框架就是Springcloud,这个名字大家听起来就很熟悉和亲切了,他依然是Spring大家族的一员,
和其他spring家族中的框架一样,能够很好地支持spring家族的其他框架。
如何选用?
因为RPC是基于API的,所以如果你的公司都是java程序员或者某个项目全是用java做的,使用Dubbo会效率更高。
反之,如果是各种语言都有的公司或者项目,使用SpringCloud会更为合适,并且SpringCloud的功能会相对更多。
3.ResTemplate
Spring提供了一个RestTemplate模板工具类,对基于Http的客户端进行了封装,并且实现了对象与json的序列化和
反序列化,非常方便。
在springboot项目中演示如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class RestTemplateTest {
@Autowired
private RestTemplate restTemplate;
@Test
public void test(){
//如果要测试需要启动spring boot项目,以便获取数据
String url = "http://localhost/user/8";
User user = restTemplate.getForObject(url, User.class);
System.out.println(user);
}
}
4.SpringCloud简介
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
顺带提一嘴,SpringCloud比较有意思的是他的版本不像其他的框架都是1.0.5啊这种正规的版本,他的版本是以英国的地铁站名来定义
4.1五大组件
- Eureka 注册中心
- Zuul,Gateway 网关(zuul慢慢被gateway取代,所以本文就只介绍讲解Gateway。如果对zuul有疑惑的可以在评论区问我)
- Ribbon 负载均衡
- Feign 服务调用
- Hystrix 熔断器
4.2Eureka注册中心详解
1.为什么需要Eureka注册中心?
如果不使用Eureka的话,我们用RestTemplate远程调用的时候,服务端就需要暴露自己的地址,不安全。而调用者需要记录服务提供者的地址,将来地址变更的时候,还需要更改,这就非常的不方便了。
而Eureka使用后,服务提供者在Eureka注册后,Eureka就把它记住了。而服务调用者这时候就不需要记住地址,只需要把自己的需求告诉Eureka。Eureka就会把符合你需求的服务告诉你。Eureka还有续约机制,或者叫心跳机制,就是提供者定期通过http方式刷新Eureka中自己的信息。
Eureka代码实现如下:
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class);
}
}
配置文件yaml如下:
server:
port: 8001
spring:
application:
name: eureka-server # 应用名称,会在Eureka中作为服务的id标识
eureka:
client:
service-url: # EurekaServer的地址
defaultZone: http://127.0.0.1:8001/eureka
register-with-eureka: false # 不注册自己,如果是集群就需要注册
fetch-registry: false #不拉取,如果集群拉取
服务提供者代码实现如下(服务注册):
@SpringBootApplication
@MapperScan("com.new.user.mapper")
@EnableDiscoveryClient // 开启Eureka客户端发现功能
public class UserServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceDemoApplication.class, args);
}
}
配置文件如下:
server:
port: 9001
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud
username: root
password: root
application:
#应用名
name: user-service
mybatis:
type-aliases-package: cn.new.user.pojo
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka
服务调用者代码如下:
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@
Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
配置文件如下:
server:
port: 8080
spring:
application:
name: consumer
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:8001/eureka
调用演示:
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{id}")
public User queryById(@PathVariable Long id){
String url = "http://localhost:9001/user/" + id;
//获取eureka中注册的user-service实例列表
List<ServiceInstance> serviceInstanceList =
discoveryClient.getInstances("user-service");
ServiceInstance serviceInstance = serviceInstanceList.get(0);
url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort()
+ "/user/" + id;
return restTemplate.getForObject(url, User.class);
}
}
2.Eureka的高可用
为什么要保持高可用?
当一台服务端的Eureka出现问题时,你整个服务都不可用了,这就很影响效率,稳定性等,这时候我们要保持服务的高可用。
实现高可用的方式就是集群!
集群后,多个Eureka Server之间会相互注册,内容也会同步到每一个节点,客户端无论访问到那个节点,都能获得所有的信息。
实现集群:
思路:如果有三个Eureka,他们之间要相互注册,假定三个Eureka分别为abc。
a要注册到b和c上。
b要注册到a和c上
c要注册到a和b上
Eureka Server代码实现:
server:
port: ${port:8001}
spring:
application:
# 应用名称,会在eureka中作为服务的id(serviceId)
name: eureka-server
eureka:
client:
service-url:
# eureka服务地址;如果是集群则是其它服务器地址,后面要加/eureka
defaultZone: ${defaultZone:http://127.0.0.1:8001/eureka}
# 是否注册自己,自身不提供服务所以不注册
#register-with-eureka: false
# 是否拉取服务
#fetch-registry: false
就是这个springboot连续启动两次,第一次用默认的8001端口,defaultZone:http://127.0.0.1:8002/eureka启动。
第二次启动在idea的Run/Debug Configurations页面来配置端口号为8002,defaultZone:http://127.0.0.1:8001/eureka,再启动。
服务提供者和服务调用者(也就是统称Eureka客户端)代码如下:
eureka:
client:
service-url: # EurekaServer地址,多个地址以','隔开
defaultZone: http://127.0.0.1:8001/eureka,http://127.0.0.1:8002/eureka
4.3负载均衡Ribbon
当服务提供者开启集群之后,此时获取的服务列表中就会有多个,这时候就需要用负载均衡来帮助我们自动选择了。
SpringCloud自动帮我们实现了负载均衡,这个组件就是Ribbon。
实例:
先开启两个服务提供者。
在服务调用者的RestTemplate上添加@LoadBalanced注解
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
调用:
@GetMapping("{id}")
public User queryById(@PathVariable("id") Long id){
String url = "http://user-service/user/" + id;
User user = restTemplate.getForObject(url, User.class);
return user;
}
就这么简单,完了。当然负载均衡还有很多算法可以选择,比如轮询,随机等,感兴趣的可以自己了解。
4.4熔断器Hystrix
简介:
这个组件名称很有意思啊,他的英文直译过来就是豪猪的意思,也不知道为什么这么叫,有知道的评论区告诉我一下,哈哈。
好了,言归正传,Hystrix的作用是为微服务系统提供保护机制。
官方是这样说的:Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。
具体问题:
雪崩问题,相信大家不会对这个词感到陌生,简单来说就是一个问题,比如一个阻塞了,线程不会释放,越来越多的请求一道来,就会有越来越多的线程会阻塞。
那么Hystrix怎么解决雪崩问题?
主要是
- 线程隔离
- 服务熔断
线程隔离:
Hystrix为每个以来服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,就是加速了失败的判定时间。
用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,或者请求超
时,则会进行降级处理。
代码实现:
在消费调用者上添加注解:@EnableCircuitBreaker
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class ConsumerApplication {
// ...
}
这三个注解可以合并成为一个注解@SpringCloudApplication
以上是关于springCloud使用(前半部)的主要内容,如果未能解决你的问题,请参考以下文章
springcloud报错-------关于 hystrix 的异常 FallbackDefinitionException:fallback method wasn't found(代码片段
SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介创建消息生产者创建消息消费者自定义消息通道分组与持久化设置 RoutingKey)(代码片段
SpringCloud系列四:Eureka 服务发现框架(定义 Eureka 服务端Eureka 服务信息Eureka 发现管理Eureka 安全配置Eureka-HA(高可用) 机制Eur(代码片段