SpringCloud入门[转]

原文链接

一、  网站的架构演变
    网络架构由最开始的三层mvc渐渐演变。传统的三层架构后来在互联网公司让几百人几千人同时开发一个项目已经变得不可行,并且会产生代码冲突的问题。基于SOA面向服务开发的架构,渐渐产生了微服务架构。微服务的架构的特点就是项目拆分成各个子项目,进行解耦操作,提供外部访问接口,属于敏捷开发,其实也可以视为面向接口开发。

一旦有了多个子项目,比如把淘宝网的订单系统和会员系统分开来看,就回产生如何管理接口、负载均衡、高并发情况下怎么限流断路等问题。那么这就有SpringCloud出现了。

那么springCloud的组件大概有哪些呢,我先简单介绍下:

  1. Eureka  服务注册中心
  2. 服务消费者 Rest 和 Fegin  --消费实现负载均衡ribbon
  3. 接口网关Zuul
  4. Hystrix  关于服务雪崩的解决方案--服务熔断、服务降级、隔离资源。

二、  Eureka
    eureka是个什么东西呢?它是一个服务注册中心。就拿上面的例子来说,如果要查看会员的订单详情,那么就要在会员系统的tomcat里面调用订单系统的tomcat里的方法。那么直接通过接口访问吗?显然这是不安全的。因此我们需要一个统一管理远程RPC调用的注册中心

如图所示,会员系统和订单都是独立能够运行的SpringBoot项目,把SpringBoot注册进eureka中,这样我们就可以通过eureka让会员系统远程调用订单系统。具体配置要怎么做呢?

首先我们要创建eureka注册中心,这里建议用idea的工具创建SpringBoot项目。

选择如图的包,如果没有则直接复制pom文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.1.3.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <groupId>my</groupId>
12     <artifactId>learning</artifactId>
13     <version>0.0.1-SNAPSHOT</version>
14     <name>learning</name>
15     <description>Demo project for Spring Boot</description>
16
17     <properties>
18         <java.version>1.8</java.version>
19         <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
20     </properties>
21
22     <dependencies>
23         <dependency>
24             <groupId>org.springframework.boot</groupId>
25             <artifactId>spring-boot-starter-web</artifactId>
26         </dependency>
27         <dependency>
28             <groupId>org.springframework.cloud</groupId>
29             <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
30         </dependency>
31
32         <dependency>
33             <groupId>org.springframework.boot</groupId>
34             <artifactId>spring-boot-starter-test</artifactId>
35             <scope>test</scope>
36         </dependency>
37     </dependencies>
38
39     <dependencyManagement>
40         <dependencies>
41             <dependency>
42                 <groupId>org.springframework.cloud</groupId>
43                 <artifactId>spring-cloud-dependencies</artifactId>
44                 <version>${spring-cloud.version}</version>
45                 <type>pom</type>
46                 <scope>import</scope>
47             </dependency>
48         </dependencies>
49     </dependencyManagement>
50
51     <build>
52         <plugins>
53             <plugin>
54                 <groupId>org.springframework.boot</groupId>
55                 <artifactId>spring-boot-maven-plugin</artifactId>
56             </plugin>
57         </plugins>
58     </build>
59
60     <repositories>
61         <repository>
62             <id>spring-milestones</id>
63             <name>Spring Milestones</name>
64             <url>https://repo.spring.io/milestone</url>
65         </repository>
66     </repositories>
67
68 </project>

然后我们创建yml文件中做如下配置

 1 #eureka的端口号
 2 server:
 3   port: 8888
 4 eureka:
 5   instance:
 6     hostname: localhost
 7   client:
 8     registerWithEureka: false
 9     fetchRegistry: false
10     serviceUrl:
11       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

然后在启动类里添加表示为eureka注册中心

@EnableEurekaServer
@SpringBootApplication
public class LearningApplication {

    public static void main(String[] args) {
        SpringApplication.run(LearningApplication.class, args);
    }

}

通过localhost:8888可以进到如下页面就表示eureka注册中心启动成功

OK,那么我们要怎么把订单系统和会员系统注册进去呢?同样创建两个SpringBoot项目,创建方式和导包方式和注册中心一样。我们关注的只有yml文件是如何把这个springBoot项目注册进去的,那么我们来看看yml文件如何配置

 1 eureka:
 2   client:
 3     serviceUrl:
 4 #      eureka的注册中心地址
 5       defaultZone: http://localhost:8888/eureka/
 6 server:
 7 #  此项目端口号
 8   port: 8889
 9 spring:
10   application:
11 #    注册进eureka的名字
12     name: order-server

创建controller包并且启动

 1 @RestController
 2 public class ordercontroller {
 3     @RequestMapping("orderTest")
 4     public String orderTest(){
 5         return "this is order";
 6     }
 7 }
 8
 9 //  启动类
10 @EnableEurekaClient
11 @SpringBootApplication
12 public class DemoApplication {
13
14     public static void main(String[] args) {
15         SpringApplication.run(DemoApplication.class, args);
16     }
17
18 }

再次打开注册中心网页,就发现已经注册进去

重复以上步骤把会员系统也注册进去

三、  PRC远程调用的方法
    远程调用的方法有两种,我们一一来细说。

1.  第一种,通过rest的方式来调用,首先我们要导入rest的pom依赖,我们要使用用户调用订单,就在用户里添加调用依赖。先解释一下什么是ribbon-----ribbon是一个负载均衡客户端 类似nginx反向代理,可以很好的控制htt和tcp的一些行为。

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-ribbon</artifactId>

</dependency>
 1 //  在启动类里把ribbon类注入spring
 2 @EnableEurekaClient
 3 @SpringBootApplication
 4 public class DemoApplication {
 5
 6     public static void main(String[] args) {
 7         SpringApplication.run(DemoApplication.class, args);
 8     }
 9     @Bean
10     @LoadBalanced        // 开启负载均衡
11     public RestTemplate restTemplate(){
12         return new RestTemplate();
13     }
14 }
15
16 public class memService{
17     @Autowired
18     private RestTemplate restTemplate;
19     @RequestMapping("/memTest")
20     public String memTest(){
21         String str = restTemplate.getForObject("http://order-server/orderTest",String.class);
22         return str;
23     }
24 }

然后我们调用会员系统的接口访问,看他会不会走到订单系统里

这就是Rest远程调用的结果。

2.  Feigin

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。

简而言之:

·Feign 采用的是基于接口的注解

·Feign 整合了ribbon
  第一步依然是导入依赖

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-feign</artifactId>

</dependency>
 1 @Service
 2 @FeignClient("order-server")
 3 public interface orderFeign {
 4     @RequestMapping("/orderTest")
 5     public String orderTest();
 6 }
 7 @RestController
 8 public class memController {
 9     @Autowired
10     private OrderFeign orderFeign;
11     @RequestMapping("/memTest")
12     public String memTest(){
13         String str = orderFeign.orderTest();
14         return str;
15     }
16 }
17
18 // 启动类
19 @EnableEurekaClient
20 @EnableFeignClients
21 @SpringBootApplication
22 public class DemoApplication {
23
24     public static void main(String[] args) {
25         SpringApplication.run(DemoApplication.class, args);
26     }
27
28 }

因此成功。这两个方式使用ribbon均衡负载,一个需要手动启动,fegin是自动启动。

四、  路由网关(ZUUL)
    路由网关有什么作用呢?上面订单和会员系统已经注册进服务中心,两者之间是通过网址直接访问。但是如果在浏览器里由订单访问会员,会因为域名不同而导致跨域问题。跨域问题的解决方案可以使用http client设置、设置请求头、nginx转发解决,那么在SpringCloud里面当然提供了一套解决方案,那就是网关ZUUL。

如图所示,当一个客户端如果直接访问时,会因为域名不同导致跨域问题。而我们所需要做的就是在前面设置一个网关变成my.com/vip  my.com/order,这样就不会产生跨域的问题。接下来我们来设置zuul。

第一步首先也要注册进eureka,导入依赖。

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>

第二步配置yml文件..

 1 #注册进eureka
 2 eureka:
 3   client:
 4     serviceUrl:
 5       defaultZone: http://localhost:8888/eureka/
 6 #配置网关端口号
 7 server:
 8   port: 8080
 9 spring:
10   application:
11     name: zuul-server
12 #配置网关转发详情
13 zuul:
14   routes:
15     api-a:
16       path: /member/**
17       service-id: member-server
18     api-b:
19       path: /order/**
20       service-id: order-server
 1 //  开启网关
 2 @EnableZuulProxy
 3 @SpringBootApplication
 4 public class DemoApplication {
 5
 6     public static void main(String[] args) {
 7         SpringApplication.run(DemoApplication.class, args);
 8     }
 9
10 }

访问配置的网关地址8080,调用member-server里的方法,成功!还可以使用网关过滤信息。具体怎样过滤不做赘述。

五、  断路器(Hystrix)
为什么需要 Hystrix?
在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC)。为了保证其高可用,单个服务又必须集群部署。由于网络原因或者自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪,甚至导致服务“雪崩”。为了解决这个问题,就出现断路器模型。

什么是服务雪崩?
分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况, 这种现象被称为服务雪崩效应. 为了应对服务雪崩, 一种常见的做法是手动服务降级. 而Hystrix的出现,给我们提供了另一种选择.

通俗来说: 就是对一个方法的PRC调用并发数量太大

服务雪崩应对策略

针对造成服务雪崩的不同原因, 可以使用不同的应对策略:

1. 流量控制

2. 改进缓存模式

3. 服务自动扩容

服务调用者降级服务

流量控制 的具体措施包括:

·网关限流

·用户交互限流

·关闭重试

什么是服务降级?
所有的RPC技术里面服务降级是一个最为重要的话题,所谓的降级指的是当服务的提供方不可使用的时候,程序不会出现异常,而会出现本地的操作调用。

通俗解释来说:就是上面例子里的会员系统访问订单系统,执行远程RPC调用方法,但是当达到一定并发量的时候,比如200个人同时访问 orderTest()方法时,tomcat的容量设置的只有150个,剩余的50个人就在外面等待一直等待。服务降级就是不让他们一直等待,调用本地的方法来fallback消息。而不再去PRC方法。

Hystrix的作用

1.断路器机制

断路器很好理解, 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.

2.Fallback

Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存.

3.资源隔离

在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池. 例如调用产品服务的Command放入A线程池, 调用账户服务的Command放入B线程池. 这样做的主要优点是运行环境被隔离开了. 这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时, 不会对系统的其他服务造成影响. 但是带来的代价就是维护多个线程池会对系统带来额外的性能开销. 如果是对性能有严格要求而且确信自己调用服务的客户端代码不会出问题的话, 可以使用Hystrix的信号模式(Semaphores)来隔离资源.

第一步首先是导入依赖

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

Rest方式调用

 1 @HystrixCommand(fallbackMethod = "testError")
 2 @RequestMapping("/memTest")
 3     public String memTest(){
 4         String str = restTemplate.getForObject("http://order-server/orderTest",String.class);
 5         return str;
 6     }
 7     public String testError(){
 8         //远程调用失败,调用此方法
 9     }
10
11
12 //启动方式
13 @EnableEurekaClient
14 @EnableHystrix
15 @SpringBootApplication
16 public class MemApp {
17
18     public static void main(String[] args) {
19         SpringApplication.run(OrderApp.class, args);
20     }

Fegin方式调用

yml文件新增配置

eign:

   hystrix:

     enabled: true

注册一个继承了Fegin接口的类到Spring容器中

 1 @Component
 2 public class MemberFeignService implements orderFeign {
 3
 4     public String errorMsg {
 5         return "出错啦";
 6     }
 7 }
 8
 9 @Service
10 @FeignClient("order-server",fallback=MemberFeignService.class)
11 public interface orderFeign {
12     @RequestMapping("/orderTest")
13     public String orderTest();
14 }

所以整个流程就是并发访问量太大导致服务雪崩。然后出发PRC的熔断机制。最后会根据情况来进行隔离资源。

原文地址:https://www.cnblogs.com/chuangqi/p/11523453.html

时间: 2024-11-03 08:12:51

SpringCloud入门[转]的相关文章

SpringCloud 入门

1. 入门概述 SpringBoot专注于快速方便的开发单个个体微服务; SpringCloud:关注全局的微服务协调治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来, 为各个微服务之间提供配置管理,服务发现,断路器,路由,微代理,事件总线,全局锁,决策竞选,分布式会话等等集成服务; 1.1 Dubbo和SpringCloud比较 Dubbo服务调用方式:RPC SpringCloud服务调用方式:REST API 2. SpringCloud 之 Hello World

【SpringCloud】(1)---SpringCloud入门篇

SpringCloud理解篇 一.微服务概述 1.什么是微服务 目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事. 与微服务相对的叫巨石 . 2.微服务与微服务架构 微服务是一种架构模式或者一种架构风格,提倡将单一应用程序划分成一组小的服务==独立部署==,服务之间相互配合.相互协调,每个服务运行于自己的==进程==中. 服务与服务间采用轻量级通讯,如HTTP的RESTful API等 避免统一的.集中式

【SpringCloud】(2)---SpringCloud入门篇

SpringCloud理解篇 一.微服务概述 1.什么是微服务 目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事. 与微服务相对的叫巨石 . 2.微服务与微服务架构 微服务是一种架构模式或者一种架构风格,提倡将单一应用程序划分成一组小的服务==独立部署==,服务之间相互配合.相互协调,每个服务运行于自己的==进程==中. 服务与服务间采用轻量级通讯,如HTTP的RESTful API等 避免统一的.集中式

SpringCloud 入门理论知识

SpringCloud 入门问题 微服务概念 微服务之间如何通信 SpringCloud与Dubbo的区别 SpringBoot与SpringCloud的关系 服务熔断和服务降级概念 微服务的优缺点 微服务技术栈 eureka和zookeeper的区别 微服务概述 微服务起源:微服务 微服务将单一应用程序划分为一组小服务,每个服务独立在及自己的进程中,通过Restful方式互相沟通.调用.每个服务提供单个业务功能,去耦合. 微服务与微服务架构 微服务:指系统中的一个服务应用. 微服务架构:架构风

SpringCloud入门1-服务注册与发现(Eureka)

前言 Oracle转让Java,各种动态语言的曝光率上升,Java工程师的未来在哪里?我觉得Spring Cloud让未来有无限可能.拖了半年之久的Spring Cloud学习就从今天开始了.中文教材不多,而且大多都是简单的离散的信息,想要找到企业级的一体化解决方案很少.不过,对于入门来说,简单就够了,等到用的时候自然而然的汇总起来. 目标是把springcloud的子项目过一遍. Component Edgware.SR2 Finchley.M7 Finchley.BUILD-SNAPSHOT

微服务和SpringCloud入门

微服务是什么 微服务的核心是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底去耦合,每个微服务提供单个业务功能的服务,一个服务做一件事情,从技术角度看就是一种小而独立的处理过程,类似进程概念,能够进行单独启动和销毁,可以拥有独立的数据库. 微服务与微服务架构的区别 微服务:它强调的事服务的大小,它关注的是某个点,是具体解决某一个问题/提供落地对应服务的一个服务应用 微服务架构:它是一种架构模式,它提成将单一应用程序划分成一组小的服务,服务之间相互配合协调,为服务提供最终价值.每个服务运行在

springcloud入门之断路器Hystrix(四)

什么是断路器 断路器模式源于Martin Fowler的Circuit Breaker一文."断路器"本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,"断路器"能够及时的切断故障电路,防止发生过载.发热.甚至起火等严重后果. 在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待.这样就不会使得线程因调用故障服务被长时间

SpringCloud入门

SpringCloud1.    springcloud概述SpringCloud是一种微服务架构,依赖于SpringBoot,主要用于服务治理(解耦),其中每一个服务都可以独立运行,服务之间没有依懒关系2.    Eureka注册中心搭建1.pom.xml配置<parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-p

SpringCloud入门(八): Zuul 过滤器详解

Zuul 过滤器 zuul 有四种过滤器类型,分别是: 1.Pre:过滤器在请求被路由之前调用.我们可利用这种过滤器实现身份验证.在集群中选择请求的微服务.记录调试信息等: 2.Routing:过滤器将请求路由到微服务.这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服: 3.Post:过滤器在路由到微服务以后执行.这种过滤器可用来为响应添加标准的HTTP Header.收集统计信息和指标.将响应从微服务发送给客户端: 4.Err