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 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怎么解决雪崩问题?

主要是

  • 线程隔离
  • 服务熔断

4.4.1 线程隔离:

Hystrix为每个以来服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,就是加速了失败的判定时间。

用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,或者请求超
时,则会进行降级处理。

代码实现:

在消费调用者上添加注解:@EnableCircuitBreaker
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class ConsumerApplication {
// ...
}

这三个注解可以合并成为一个注解@SpringCloudApplication
 

编写失败逻辑:

当服务调用出现意外或者故障时,框架的编写者想到应该快速失败,因此需要提前编写好失败时的降级处理逻 辑,要使用HystrixCommand来完成。如下:

@RestController
@RequestMapping("/consumer")
@Slf4j
public class ConsumerController {

@Autowired
private RestTemplate restTemplate;

@Autowired
private DiscoveryClient discoveryClient;

@GetMapping("{id}")
@HystrixCommand(fallbackMethod = "queryByIdFallback")
public String queryById(@PathVariable Long id){
String url = "http://localhost:9091/user/" + id;
url = "http://user-service/user/" + id;
return restTemplate.getForObject(url, String.class);
}

public String queryByIdFallback(Long id){

return "对不起,出错了!";
}
}

        

说明: @HystrixCommand(fallbackMethod = "queryByIdFallBack"):用来声明一个降级逻辑的方法

 

默认的Fallback:

刚才把fallback写在了某个业务方法上,如果这样的方法很多,那岂不是要写很多。所以可以把Fallback配置加在类 上,实现默认fallback;

@RestController
@RequestMapping("/consumer")
@Slf4j
@DefaultProperties(defaultFallback = "defaultFallback")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{id}")
//@HystrixCommand(fallbackMethod = "queryByIdFallback")
@HystrixCommand
public String queryById(@PathVariable Long id){
String url = "http://localhost:9091/user/" + id;
url = "http://user-service/user/" + id;
return restTemplate.getForObject(url, String.class);
}
public String queryByIdFallback(Long id){
log.error("查询用户信息失败。id:{}", id);
return "对不起,网络太拥挤了!";
}
public String defaultFallback(){
return "默认提示:对不起,网络太拥挤了!";
}
}

4.4.2 服务熔断

在服务熔断中,使用的熔断器,也叫断路器,其英文单词为:Circuit Breaker

熔断机制与家里使用的电路熔断原理类似;当如果电路发生短路的时候能立刻熔断电路,避免发生灾难。

在分布式系 统中应用服务熔断后;服务调用方可以自己进行判断哪些服务反应慢或存在大量超时,可以针对这些服务进行主动熔 断,防止整个系统被拖垮。

Hystrix的服务熔断机制,可以实现弹性容错;当服务请求情况好转之后,可以自动重连。通过断路的方式,将后续 请求直接拒绝,一段时间(默认5秒)之后允许部分请求通过,如果调用成功则回到断路器关闭状态,否则继续打 开,拒绝请求的服务。

 

 

 

后半部地址:https://blog.csdn.net/strandtrack/article/details/117087359

你可能感兴趣的:(SpringCloud)