Spring cloud应该怎么入门?(图文,很详细)下

简介: Spring cloud应该怎么入门?(图文,很详细)下

六、引出RestTemplate和Ribbon

通过Eureka服务治理框架,我们可以通过服务名来获取具体的服务实例的位置了(IP)。一般在使用SpringCloud的时候不需要自己手动创建HttpClient来进行远程调用。

可以使用Spring封装好的RestTemplate工具类,使用起来很简单:

// 传统的方式,直接显示写死IP是不好的!
    //private static final String REST_URL_PREFIX = "http://localhost:8001";
  // 服务实例名
    private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
    /**
     * 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,
     * ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
     */
    @Autowired
    private RestTemplate restTemplate;
    @RequestMapping(value = "/consumer/dept/add")
    public boolean add(Dept dept) {
        return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
    }

为了实现服务的高可用,我们可以将服务提供者集群。比如说,现在一个秒杀系统设计出来了,准备上线了。在11月11号时为了能够支持高并发,我们开多台机器来支持并发量。

网络异常,图片无法展示
|

现在想要这三个秒杀系统合理摊分用户的请求(专业来说就是负载均衡),可能你会想到nginx。

其实SpringCloud也支持的负载均衡功能,只不过它是客户端的负载均衡,这个功能实现就是Ribbon!

负载均衡又区分了两种类型:

客户端负载均衡(Ribbon)

服务实例的清单在客户端,客户端进行负载均衡算法分配。

(从上面的知识我们已经知道了:客户端可以从Eureka Server中得到一份服务清单,在发送请求时通过负载均衡算法,在多个服务器之间选择一个进行访问)

服务端负载均衡(Nginx)

服务实例的清单在服务端,服务器进行负载均衡算法分配

所以,我们的图可以画成这样:

网络异常,图片无法展示
|

6.1Ribbon细节

Ribbon是支持负载均衡,默认的负载均衡策略是轮询,我们也是可以根据自己实际的需求自定义负载均衡策略的。

@Configuration
public class MySelfRule
{
  @Bean
  public IRule myRule()
  {
    //return new RandomRule();// Ribbon默认是轮询,我自定义为随机
    //return new RoundRobinRule();// Ribbon默认是轮询,我自定义为随机
    return new RandomRule_ZY();// 我自定义为每台机器5次
  }
}

实现起来也很简单:继承AbstractLoadBalancerRule类,重写public Server choose(ILoadBalancer lb, Object key)即可。

SpringCloud 在CAP理论是选择了AP的,在Ribbon中还可以配置重试机制的(有兴趣的同学可以去搜搜)~

举个例子:

3y跟女朋友过了几个月,又去东方宝泰了。由于记性不好,又去物业那弄了一份东方宝泰商户清单。

这次看到东方宝泰又开了一间麦当劳,一间在二楼,一间在三楼。原来生意太好了,为了能提高用户体验,在二楼多开了一间麦当劳。

这时,3y问女朋友:“去哪间麦当劳比较好?要不我们抛硬币决定?”3y女朋友说:”你是不是傻,肯定哪间近去哪间啊“

优秀博文:

撸一撸Spring Cloud Ribbon的原理-负载均衡策略:https://www.cnblogs.com/kongxianghai/p/8477781.html

七、引出Hystrix

到目前为止,我们的服务看起来好像挺好的了:能够根据服务名来远程调用其他的服务,可以实现客户端的负载均衡。

网络异常,图片无法展示
|

但是,如果我们在调用多个远程服务时,某个服务出现延迟,会怎么样??

网络异常,图片无法展示
|

高并发的情况下,由于单个服务的延迟,可能导致所有的请求都处于延迟状态,甚至在几秒钟就使服务处于负载饱和的状态,资源耗尽,直到不可用,最终导致这个分布式系统都不可用,这就是“雪崩”。

针对上述问题, Spring Cloud Hystrix实现了断路器、线程隔离等一系列服务保护功能。

Fallback(失败快速返回):当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝), 向调用方返回一个错误响应, 而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

资源/依赖隔离(线程池隔离):它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响, 而不会拖慢其他的依赖服务。

Hystrix提供几个熔断关键参数:滑动窗口大小(20)、 熔断器开关间隔(5s)、错误率(50%)

每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。

直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

Hystrix还有请求合并、请求缓存这样强大的功能,在此我就不具体说明了,有兴趣的同学可继续深入学习~

7.1Hystrix仪表盘

Hystrix仪表盘:它主要用来实时监控Hystrix的各项指标信息。通过Hystrix Dashboard反馈的实时信息,可以帮助我们快速发现系统中存在的问题,从而及时地采取应对措施。

启动时的页面:

网络异常,图片无法展示
|

监控单服务的页面:

网络异常,图片无法展示
|

我们现在的服务是这样的:

网络异常,图片无法展示
|

除了可以开启单个实例的监控页面之外,还有一个监控端点 /turbine.stream是对集群使用的。 从端点的命名中,可以引入Turbine, 通过它来汇集监控信息,并将聚合后的信息提供给 HystrixDashboard 来集中展示和监控

网络异常,图片无法展示
|

举个例子:

3y和女朋友决定去万达玩,去到万达的停车场发现在负一层已经大大写上“负一层已停满,请下负二层,负二层空余停车位还有100个!”

这时,3y就跟女朋友说:“万达停车场是做得挺好的,如果它没有直接告知我负一层已满,可能我就去负一层找位置了,要是一堆人跑去负一层但都找不到车位的话,恐怕就塞死了”。3y接着说:“看停车位的状态也做得不错,在停车位上头有一个感应(监控),如果是红色就代表已被停了,如果是绿色就说明停车位是空的”。

3y女朋友不屑的说:“你话是真的多”

参考资料:

Hystrix ,为什么说它是每个系统不可或缺的开源框架?https://zhuanlan.zhihu.com/p/34304136

深入理解Hystrix之文档翻译:https://zhuanlan.zhihu.com/p/28523060

谈谈我对服务熔断、服务降级的理解:https://blog.csdn.net/guwei9111986/article/details/51649240

Hystrix几篇文章《青芒》:https://segmentfault.com/u/yedge/articles

八、引出Feign

上面已经介绍了Ribbon和Hystrix了,可以发现的是:他俩作为基础工具类框架广泛地应用在各个微服务的实现中。我们会发现对这两个框架的使用几乎是同时出现的。

为了简化我们的开发,Spring Cloud Feign出现了!它基于 Netflix Feign 实现,整合了 Spring Cloud Ribbon 与 Spring Cloud Hystrix, 除了整合这两者的强大功能之外,它还提 供了声明式的服务调用(不再通过RestTemplate)。

Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。

下面就简单看看Feign是怎么优雅地实现远程调用的:

服务绑定:

// value --->指定调用哪个服务
// fallbackFactory--->熔断器的降级提示
@FeignClient(value = "MICROSERVICECLOUD-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class)
public interface DeptClientService {
    // 采用Feign我们可以使用SpringMVC的注解来对服务进行绑定!
    @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
    public Dept get(@PathVariable("id") long id);
    @RequestMapping(value = "/dept/list", method = RequestMethod.GET)
    public List<Dept> list();
    @RequestMapping(value = "/dept/add", method = RequestMethod.POST)
    public boolean add(Dept dept);
}

Feign中使用熔断器:

/**
 * Feign中使用断路器
 * 这里主要是处理异常出错的情况(降级/熔断时服务不可用,fallback就会找到这里来)
 */
@Component // 不要忘记添加,不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public Dept get(long id) {
                return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
                        .setDb_source("no this database in MySQL");
            }
            @Override
            public List<Dept> list() {
                return null;
            }
            @Override
            public boolean add(Dept dept) {
                return false;
            }
        };
    }
}

调用:

网络异常,图片无法展示
|

九、引出Zuul

基于上面的学习,我们现在的架构很可能会设计成这样:

网络异常,图片无法展示
|

这样的架构会有两个比较麻烦的问题:

1.路由规则与服务实例的维护间题:外层的负载均衡(nginx)需要维护所有的服务实例清单(图上的OpenService)

2.签名校验、 登录校验冗余问题:为了保证对外服务的安全性, 我们在服务端实现的微服务接口,往往都会有一定的权限校验机制,但我们的服务是独立的,我们不得不在这些应用中都实现这样一套校验逻辑,这就会造成校验逻辑的冗余。

还是画个图来理解一下吧:

网络异常,图片无法展示
|

每个服务都有自己的IP地址,Nginx想要正确请求转发到服务上,就必须维护着每个服务实例的地址!

更是灾难的是:这些服务实例的IP地址还有可能会变,服务之间的划分也很可能会变。

http://123.123.123.123
http://123.123.123.124
http://123.123.123.125
http://123.123.123.126
http://123.123.123.127

购物车和订单模块都需要用户登录了才可以正常访问,基于现在的架构,只能在购物车和订单模块都编写校验逻辑,这无疑是冗余的代码。

为了解决上面这些常见的架构问题,API网关的概念应运而生。在SpringCloud中了提供了基于Netfl ix Zuul实现的API网关组件Spring Cloud Zuul。

Spring Cloud Zuul是这样解决上述两个问题的:

SpringCloud Zuul通过与SpringCloud Eureka进行整合,将自身注册为Eureka服务治理下的应用,同时从Eureka中获得了所有其他微服务的实例信息。外层调用都必须通过API网关,使得将维护服务实例的工作交给了服务治理框架自动完成。

在API网关服务上进行统一调用来对微服务接口做前置过滤,以实现对微服务接口的拦截和校验。

Zuul天生就拥有线程隔离和断路器的自我保护功能,以及对服务调用的客户端负载均衡功能。也就是说:Zuul也是支持Hystrix和Ribbon。

关于Zuul还有很多知识点(由于篇幅问题,这里我就不细说了):

路由匹配(动态路由)

过滤器实现(动态过滤器)

默认会过滤掉Cookie与敏感的HTTP头信息(额外配置)

9.1可能对Zuul的疑问

Zuul支持Ribbon和Hystrix,也能够实现客户端的负载均衡。我们的Feign不也是实现客户端的负载均衡和Hystrix的吗?既然Zuul已经能够实现了,那我们的Feign还有必要吗?

网络异常,图片无法展示
|

或者可以这样理解:

zuul是对外暴露的唯一接口相当于路由的是controller的请求,而Ribbonhe和Fegin路由了service的请求

zuul做最外层请求的负载均衡 ,而Ribbon和Fegin做的是系统内部各个微服务的service的调用的负载均衡

有了Zuul,还需要Nginx吗?他俩可以一起使用吗?

我的理解:Zuul和Nginx是可以一起使用的(毕竟我们的Zuul也是可以搭成集群来实现高可用的),要不要一起使用得看架构的复杂度了(业务)~~~

参考资料:

微服务与API网关(上): 为什么需要API网关?:http://blog.didispace.com/hzf-ms-apigateway-1/

谈谈 API 网关:https://www.jianshu.com/p/b52a2773e75f

谈谈微服务中的 API 网关(API Gateway):https://www.cnblogs.com/savorboard/p/api-gateway.html

API网关性能比较:NGINX vs. ZUUL vs. Spring Cloud Gateway :http://www.360doc.com/content/18/0208/05/46368139_728502763.shtml

谈API网关的背景、架构以及落地方案:http://www.infoq.com/cn/news/2016/07/API-background-architecture-floo

zuul和nginx:https://zhuanlan.zhihu.com/p/37385481

十、引出SpringCloud Config

随着业务的扩展,我们的服务会越来越多,越来越多。每个服务都有自己的配置文件。

既然是配置文件,给我们配置的东西,那难免会有些改动的。

比如我们的Demo中,每个服务都写上相同的配置文件。万一我们有一天,配置文件中的密码需要更换了,那就得三个都要重新更改。

在分布式系统中,某一个基础服务信息变更,都 很可能会引起一系列的更新和重启

Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

简单来说,使用Spring Cloud Config就是将配置文件放到统一的位置管理(比如GitHub),客户端通过接口去获取这些配置文件。

在GitHub上修改了某个配置文件,应用加载的就是修改后的配置文件。

网络异常,图片无法展示
|

SpringCloud Config其他的知识:

在SpringCloud Config的服务端, 对于配置仓库的默认实现采用了Git,我们也可以配置SVN。

配置文件内的信息加密和解密

修改了配置文件,希望不用重启来动态刷新配置,配合Spring Cloud Bus 使用~

使用SpringCloud Config可能的疑问:application.yml和 bootstrap.yml区别

https://www.cnblogs.com/BlogNetSpace/p/8469033.html

总结

本文主要写了SpringCloud的基础知识,希望大家看完能有所帮助~

SpringCloud的资料也很多,我整理一些我认为比较好,想要深入的同学不妨看看下边的资源~~~

SpringCloud系列文章参考资料:

史上最简单的 SpringCloud 教程 | 终章https://blog.csdn.net/forezp/article/details/70148833

Spring Cloud基础教程《程序员DD》http://blog.didispace.com/Spring-Cloud%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/

Spring Cloud 系列文章《纯洁的微笑》:http://www.ityouknow.com/spring-cloud.html

SpringCloud系列文章:https://www.cnblogs.com/woshimrf/tag/SpringCloud/

SpringCloud系列文章《狂小白》:https://www.cnblogs.com/huangjuncong/tag/SpringCloud/

SpringCloud官方文档:http://projects.spring.io/spring-cloud/

Spring Cloud 中文文档:https://springcloud.cc/spring-cloud-dalston.html#_appendix_compendium_of_configuration_properties

参考书籍:

《SpringCloud 微服务实战》

SpringCloud GitHub Demo(看完文章的同学可以自己练手玩玩,写好了ReadMe了):

https://github.com/ZhongFuCheng3y/msc-Demo

目录
相关文章
|
18小时前
|
监控 安全 Java
Spring cloud原理详解
Spring cloud原理详解
7 0
|
2天前
|
安全 Java 数据库连接
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
|
5天前
|
消息中间件 负载均衡 Java
【Spring Cloud 初探幽】
【Spring Cloud 初探幽】
13 1
|
6天前
|
Java 开发者 微服务
Spring Cloud原理详解
【5月更文挑战第4天】Spring Cloud是Spring生态系统中的微服务框架,包含配置管理、服务发现、断路器、API网关等工具,简化分布式系统开发。核心组件如Eureka(服务发现)、Config Server(配置中心)、Ribbon(负载均衡)、Hystrix(断路器)、Zuul(API网关)等。本文讨论了Spring Cloud的基本概念、核心组件、常见问题及解决策略,并提供代码示例,帮助开发者更好地理解和实践微服务架构。此外,还涵盖了服务通信方式、安全性、性能优化、自动化部署、服务网格和无服务器架构的融合等话题,揭示了微服务架构的未来趋势。
31 6
|
10天前
|
JSON Java Apache
Spring Cloud Feign 使用Apache的HTTP Client替换Feign原生httpclient
Spring Cloud Feign 使用Apache的HTTP Client替换Feign原生httpclient
|
11天前
|
负载均衡 Java 开发者
Spring Cloud:一文读懂其原理与架构
Spring Cloud 是一套微服务解决方案,它整合了Netflix公司的多个开源框架,简化了分布式系统开发。Spring Cloud 提供了服务注册与发现、配置中心、消息总线、负载均衡、熔断机制等工具,让开发者可以快速地构建一些常见的微服务架构。
|
12天前
|
消息中间件 Java RocketMQ
Spring Cloud RocketMQ:构建可靠消息驱动的微服务架构
【4月更文挑战第28天】消息队列在微服务架构中扮演着至关重要的角色,能够实现服务之间的解耦、异步通信以及数据分发。Spring Cloud RocketMQ作为Apache RocketMQ的Spring Cloud集成,为微服务架构提供了可靠的消息传输机制。
27 1
|
12天前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo: 微服务通信的高效解决方案
【4月更文挑战第28天】在微服务架构的发展中,服务间的高效通信至关重要。Spring Cloud Dubbo 提供了一种基于 RPC 的通信方式,使得服务间的调用就像本地方法调用一样简单。本篇博客将探讨 Spring Cloud Dubbo 的核心概念,并通过具体实例展示其在项目中的实战应用。
15 2
|
12天前
|
监控 Java Sentinel
Spring Cloud Sentinel:概念与实战应用
【4月更文挑战第28天】在分布式微服务架构中,确保系统的稳定性和可靠性至关重要。Spring Cloud Sentinel 为微服务提供流量控制、熔断降级和系统负载保护,有效预防服务雪崩。本篇博客深入探讨 Spring Cloud Sentinel 的核心概念,并通过实际案例展示其在项目中的应用。
23 0