使用SpringBoot构建单体项目有一段时间了,准备对一个老项目重构时引入SpringCloud微服务,以此奠定后台服务能够应对未知的业务需求。

现在SOA架构下的服务管理面临很多挑战,比如面临一个非常大型的代码库,版本合并困难,甚至存在不同项目不同版本,维护量极其庞大,无法快速响应不同的业务需求;同时这些大型代码库由于没有前后端分离,导致打包成一个大型的WAR包,服务自身无法独立打包部署,在运行阶段,随着项目应用规模扩大无法平滑伸缩,只能通过部署新的应用服务器粗粒度应付;还有一个问题就是大量环境配置的管理相当复杂。

从单体迁移到微服务的实践之道是:前后端分离,后端暴露restful api给前端。只有前后端分离,前端和后端才能分离部署,只有使用基于http的restful接口,后端才与周围环境真正分离,如果只是使用RPC,双方还和java接口耦合,而使用rest/json数据格式,双方只要进行序列化和反序列化,双方耦合没有那么紧密,这非常类似异步通讯中消息数据格式的耦合,用性能小降代价换来后端服务与周围环境的解耦,只有这样我们才能对后端再进行切分成微小服务,打包进入Docker,放入K8s平台中调度运行。说白了,挖树需要把树根与周围分离,整个树才能移植,后端服务只有通过rest API前后端分离,才能安装上Docker+K8s。

SpringBoot默认情况下已经开启restful端口,这种约定大于配置的做法大大简化了编程过程,同时也“强行”将微服务与Rest接口进行了绑定。

系统=大前端(SpringMVC或SPA等)+REST+后端

当后端服务从前端的约束羁绊中解放出来以后,完全走向了自由,可以为多个前端客户端或其他系统提供服务API,当然系统也由此走上了分布式不归路,服务之间调用不再通过JVM内部直接方法调用,而是通过rest/json交互,整个系统的复杂性也由此上升,SpringCloud为基于SpringBoot的分布式微服务开发提供了透明且开箱即用的开发方式,将很多属于系统管理配置职责带入了开发,由此对开发人员素质提出更高要求,这也是devops一词的来由,devops=开发+运维。

下面谈谈SpringCloud的几个分布式架构组件是如何简化分布式开发和系统运维配置的。

配置服务器

配置服务器能够将各种配置集中在一起,配置信息是一种键值对,暴露rest API,可以加密,能够快速失效,也可以强制更新,在运行时能够通过下面方式强行刷新到最新配置:

curl –X POST http://localhost:8080/refresh

CONFIG SERVER

这是一个很简单方式,但是也要防止程序员不小心一个delete数据库的灾难事情发生。

API网关

如果说后端微服务组成了一个服务群,这个群是群主的,群主可以批准你加入也可以剔除你,API网关就是微服务的守门人,专业上称为边缘服务,微服务是核心,它是边缘。

API网关的群主职责也还有其他:

1.设计上的适配层,或称Facade模式,后端微服务可能过于细粒度,通过API网关进行内外适配,前后端转换,如果220v转换成110v一样。

2.运行阶段:将外部请求路由分发到内部各个微服务,负载平衡和路由策略是需要的。

Springcloud之前使用NETFLIX ZUUL作为API网关,虽然它有很多好处,容易设置,限速和日志过滤,可授权,智能负载平衡,攻击探测和阻止,但是很难管理网关和API的超时。使用Spring ZUUL编程时,最大特征就是编制各种过滤器,事前过滤器 路由过滤器和事后过滤器。

在很多地方,也有使用Nginx作为API网关,Nginx官方有不少文章讲述Nginx如何在微服务架构中扮演重要角色的.

NGINX和zuul 1.0是堵塞的,而Zuul 2.0、Spring Cloud Gateway和Linkerd, Envoy是非堵塞的,后两者借助API网关推出服务网格概念,能够统一对成千上百微服务进行管理,不过这好像又回到了服务器为王的时代,微服务好不容易打破服务器的约束,走出服务器的多租户空间独立成王,现在又会被打着API网关旗帜的新的统一管理方式关起来吗?

SpringCloud提供Reactive响应式架构,使得分布式网络通讯效率大大提高,分布式系统的IO不再成为性能瓶颈。

服务发现

在分布式环境,许多服务实例都不断因为开发而不断变化,时而上线,时而下线,微服务之间如何好好发现活着的对方也是个问题,这就是需要服务注册器,每个微服务向其注册,其他需要调用的微服务通过注册器发现对方进行调用,调用时可加入负载平衡策略.

Spring Cloud推荐使用NETFLIX EUREKA,用CAP定理来看,它属于AP,而Zookeeper属于CP,因此后者不是非常适合应用在服务发现场合,它本来诞生于大数据应用场景,虽然后来被Hadoop抛弃。

NETFLIX EUREKA易于设置,基于Rest的服务注册,支持复制,支持客户端缓存,速度快虽然数据容易不一致(AP)。

如果直接基于Eureka进行服务注册和发现,需要手工将负载平衡策略与REST处理绑定在一起,而通过Feign组件能够默认实现负载平衡+REST方式的通讯,只要像普通REST调用即可,大大提高了开发效率,其内部使用Ribbon负载平衡器和hystrix断路器。

@FeignClient(name="PengProducerService")
public interface ConsumerService {

@GetMapping("/articles")
List<Article> getAllArticles();
}
运维

SpringCloud提供了SLEUTH方便跟踪请求级别的微服务调用,是一种分布式跟踪解决方案,与Zipkin等结合,形成生产运维监控管理,能够掌握每个微服务实例调用时间。

HYSTRIX断路器能够增强系统的弹性,在微服务无法访问时重试,重试几次后就放弃,也能进行快速失效,不把时间耗费在无谓的等待上,防止故障爆炸。提供仪表板实时情况。

身份验证和授权

前后端通过REST分离以后,需要一种基于令牌的方法来与前端对话,还需要对每个请求进行身份验证和权限验证。

OAuth2是一种开放的标准授权协议规范,虽然目前不能完全取代OAuth1.0a,但是会不断日趋完善。

一旦用户请求通过OAuth进行了身份验证和权限验证,API网关会放行这个请求到后端微服务中,但是如果请求中没有携带身份信息,在后端微服务实例之间转了几个圈后,微服务无法确保是否可以接受这个请求了,因此,需要在每个请求里携带通过验证的用户身份信息,这就需要采取JWT(JSON WEB TOKEN), JWT能使用HMACSHA256进行签名,或者使用RSA进行公有/私有键值对签名,可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快,由此避免了各个微服务多次查询数据库以搞清楚当前请求的身份信息。

总结:

了解了SpringCloud架构以后,迁移之路也就明细了:

整个核心是服务注册和发现,因此首先开始应用服务注册,但是服务注册中心容易变成单点风险,谈不上高可用性,一旦这个单点崩溃,全局奔溃,那么准备两套注册中心,引入配置服务器,在两套注册中心之间进行切换变得非常重要,由于配置服务器一旦修改,需要通知很多组件,因此需要引入异步通讯,由此需要Spring Cloud Bus。

第一步:注册中心

第二步:配置服务器

第三步:Spring Cloud bus通讯总线

第四步是数据库的切分,使得每个微服务只有一两个数据库。

第五步是切入基于事件的事务架构,比如EventSourcing等等。

第六步是安装上底座:Docker化和Kubernetes调度Paas平台化。
---------------------

参考:https://blog.csdn.net/gupao123456/article/details/81030839

使用SpringCloud将单体迁移至微服务的更多相关文章

  1. 微服务实践(七):从单体式架构迁移到微服务架构 - DockOne.io

    原文:微服务实践(七):从单体式架构迁移到微服务架构 - DockOne.io [编者的话]这是用微服务开发应用系列博客的第七篇也是最后一篇.第一篇中介绍了微服务架构模式,并且讨论了微服架构的优缺点: ...

  2. ABP VNext从单体切换到微服务

    注:此处的微服务只考虑服务部分,不考虑内外层网关.认证等. ABP VNext从单体切换到微服务,提供了相当大的便利性,对于各模块内部不要做任何调整,仅需要调整承载体即可. ABP can help ...

  3. 学习一下 SpringCloud (一)-- 从单体架构到微服务架构、代码拆分(maven 聚合)

    一.架构演变 1.系统架构.集群.分布式系统 简单理解 (1)什么是系统架构? [什么是系统架构?] 系统架构 描述了 在应用程序内部,如何根据 业务.技术.灵活性.可扩展性.可维护性 等因素,将系统 ...

  4. SpringCloud之旅第一篇-微服务概念

    一.单体架构的问题 微服务为什么会出现?在学习Springboot的时候知道Springboot极大的简化了我们的开发,我们可以快速的进行业务开发,Springboot单体应用在项目的开发初期能够满足 ...

  5. SpringCloud系列三:将微服务注册到Eureka Server上

    1. 回顾 通过上篇博客的讲解,我们知道硬编码提供者地址的方式有不少问题.要想解决这些问题,服务消费者需要一个强大的服务发现机制,服务消费者使用这种机制获取服务提供者的网络信息.不仅如此,即使服务提供 ...

  6. springCloud和docker笔记(1)——微服务架构概述

    1.微服务设计原则 1)单一职责原则:只关注整个系统中单独.有界限的一部分(SOLID原则之一) 2)服务自治原则:具备独立的业务能力和运行环境,可独立开发.测试.构建.部署 3)轻量级通信机制:体量 ...

  7. SpringCloud(一)之微服务核心组件Eureka(注册中心)的介绍和使用

    一 Eureka服务治理体系1.1 服务治理服务治理是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现. Spring Cloud Eureka是Spring Clou ...

  8. SpringCloud学习系列-构建部门微服务消费者Module

    1.新建microservicecloud-consumer-dept-80 2.Pom <project xmlns="http://maven.apache.org/POM/4.0 ...

  9. 系列免费课程汇总(Java、单体应用、微服务、物联网、SaaS)

    概述 2020年春节尽在眼前,又忙碌了一年的你一定有很多收获:是升职加薪,还是收获爱情?是买房置业,还是新添人口? 我在2019年的最大收获是:我的第二枚千金诞生,使我顺利加入富豪行列! 新年伊始我们 ...

随机推荐

  1. 重置gitlab管理员密码

    gitlab web管理员登录密码忘记以后可以用如下方式修改密码(本演示系统为Linux-CentOS6.6): [root@localhost ~]# gitlab-rails console pr ...

  2. 带你入门 CSS Grid 布局

    前言 三月中旬的时候,有一个对于 CSS 开发者来说很重要的消息,最新版的 Firefox 和 Chrome 已经正式支 CSS Grid 这一新特性啦.没错:我们现在就可以在最流行的两大浏览器上玩转 ...

  3. 前端基础知识之HTML

    [1: What does a doctype do?] 1: doctype是html文件的第一行代码,意味着它的前面有注释都不行.所以要要写在<html>标签前面,而且它不属于html ...

  4. Java基础--方法的定义

    1.为什么要有方法? 方法(又叫函数)就是一段特定功能的代码块.方法提高程序的复用性和可读性. 比如,有了方法,我们可以把要重复使用的一段代码提炼出来,然后在每个需要执行这段代码的地方去调用即可. 2 ...

  5. JZOJ 1301. treecut

    1301. treecut (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Description 有一个N个节点的无根树,各节 ...

  6. ubuntu16.04安装库、插件报错:

    安装一些插件.库,遇到报错 Could not fetch URL https://pypi.org/simple/pytest-pycodestyle/: There was a problem c ...

  7. 【MySQL 原理分析】之 Explain & Trace 深入分析全模糊查询走索引的原理

    一.背景 今天,交流群有一位同学提出了一个问题.看下图: 之后,这位同学确实也发了一个全模糊查询走索引的例子: 到这我们可以发现,这两个sql最大的区别是:一个是查询全字段(select *),而一个 ...

  8. var, let ,const区别

    ES6中加入了let,const字符,先说说新的区别: 作用域:let 声明的变量只在它所在的代码块内有效,而且不存在变量提升,即变量可以在声明之前使用,值为undefined.let未声明变量前会报 ...

  9. java原子操作CAS

    本次内容主要讲原子操作的概念.原子操作的实现方式.CAS的使用.原理.3大问题及其解决方案,最后还讲到了JDK中经常使用到的原子操作类. 1.什么是原子操作? 所谓原子操作是指不会被线程调度机制打断的 ...

  10. Leetcode 1160: 拼写单词

    给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌 ...