刚开始进入软件行业时还是单体应用的时代,前后端分离的概念都还没普及,开发的时候需要花大量的时间在“强大”的JSP上面,那时候SOA已经算是新技术了。现在,微服务已经大行其道,有哪个互联网产品不说自己是微服务架构呢?

但是,对于微服务的理解每个人都不太一样,这篇文章主要是聊一聊我对微服务的理解以及如何搭建经典的微服务架构,目的是梳理一下自己的一些想法,如果存在不同看法的欢迎指正!

什么是微服务

首先,什么是微服务呢?

单体应用

相对的,要理解什么是微服务,那么可以先理解什么是单体应用,在没有提出微服务的概念的“远古”年代,一个软件应用,往往会将应用所有功能都开发和打包在一起,那时候的一个B/S应用架构往往是这样的:

B/S

但是,当用户访问量变大导致一台服务器无法支撑时怎么办呢?加服务器加负载均衡,架构就变成这样了:

B/S+负载均衡

后面发现把静态文件独立出来,通过CDN等手段进行加速,可以提升应用的整体相应,单体应用的架构就变成:

B/S+前后端分离

上面3中架构都还是单体应用,只是在部署方面进行了优化,所以避免不了单体应用的根本的缺点:

  • 代码臃肿,应用启动时间长;(代码超过1G的项目都有!)

  • 回归测试周期长,修复一个小小bug可能都需要对所有关键业务进行回归测试。

  • 应用容错性差,某个小小功能的程序错误可能导致整个系统宕机;

  • 伸缩困难,单体应用扩展性能时只能整个应用进行扩展,造成计算资源浪费。

  • 开发协作困难,一个大型应用系统,可能几十个甚至上百个开发人员,大家都在维护一套代码的话,代码merge复杂度急剧增加。

微服务

我认为任何技术的演进都是有迹可循的,任何新技术的出现都是为了解决原有技术无法解决的需求,所以,微服务的出现就是因为原来单体应用架构已经无法满足当前互联网产品的技术需求。

在微服务架构之前还有一个概念:SOA(Service-Oriented Architecture)-面向服务的体系架构。我认为的SOA只是一个架构模型的方法论,并不是一个明确而严谨的架构标准,只是后面很多人将SOA与The Open Group的SOA参考模型等同了,认为严格按照TOG-SOA标准的才算真正的SOA架构。SOA就已经提出的面向服务的架构思想,所以微服务应该算是SOA的一种演进吧。

撇开架构先不说,什么样的服务才算微服务呢?

  • 单一职责的。一个微服务应该都是单一职责的,这才是“微”的体现,一个微服务解决一个业务问题(注意是一个业务问题而不是一个接口)。

  • 面向服务的。将自己的业务能力封装并对外提供服务,这是继承SOA的核心思想,一个微服务本身也可能使用到其它微服务的能力。

我觉得满足以上两点就可以认为典型的微服务。

微服务典型架构

微服务架构,核心是为了解决应用微服务化之后的服务治理问题。

应用微服务化之后,首先遇到的第一个问题就是服务发现问题,一个微服务如何发现其他微服务呢?最简单的方式就是每个微服务里面配置其他微服务的地址,但是当微服务数量众多的时候,这样做明显不现实。关注微信公众号:互联网架构师,在后台回复:2T,可以获取我整理的架构师全套教程,都是干货。所以需要使用到微服务架构中的一个最重要的组件:服务注册中心,所有服务都注册到服务注册中心,同时也可以从服务注册中心获取当前可用的服务清单: 

服务注册中心

解决服务发现问题后,接着需要解决微服务分布式部署带来的第二个问题:服务配置管理的问题。当服务数量超过一定程度之后,如果需要在每个服务里面分别维护每一个服务的配置文件,运维人员估计要哭了。那么,就需要用到微服务架构里面第二个重要的组件:配置中心,微服务架构就变成下面这样了:

配置中心

以上应用内部的服务治理,当客户端或外部应用调用服务的时候怎么处理呢?服务A可能有多个节点,服务A、服务B和服务C的服务地址都不同,服务授权验证在哪里做?这时,就需要使用到服务网关提供统一的服务入口,最终形成典型微服务架构:

典型微服务架构

上面是一个典型的微服务架构,当然微服务的服务治理还涉及很多内容,比如:

  • 通过熔断、限流等机制保证高可用;

  • 微服务之间调用的负载均衡;

  • 分布式事务(2PC、3PC、TCC、LCN等);

  • 服务调用链跟踪等等。

微服务框架

目前国内企业使用的微服务框架主要是Spring Cloud和Dubbo(或者DubboX),但是Dubbo那两年的停更严重打击了开发人员对它的信心,Spring Cloud已经逐渐成为主流,比较两个框架的优劣势的文章在网上有很多,这里就不重复了,选择什么框架还是按业务需求来吧,业务框架决定技术框架。

Spring Cloud全家桶提供了各种各样的组件,基本可以覆盖微服务的服务治理的方方面面,以下列出了Spring Cloud一些常用组件:

Spring Cloud常用组件

搭建典型微服务架构

本章节主要介绍如何基于Spring Cloud相关组件搭建一个典型的微服务架构。

首先,创建一个Maven父项目spring-cloud-examples,用于管理项目依赖包版本。由于Spring Cloud组件很多,为保证不同组件之间的兼容性,一般通过spring-cloud-dependencies统一管理Spring Cloud组件版本,而非每个组件单独引入。

pom.xml配置如下:

    <!-- 继承SpringBoot父项目,注意与SpringCloud版本的匹配 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.4.RELEASE</version></parent><properties><spring.boot.version>2.1.4.RELEASE</spring.boot.version><spring.cloud.version>Greenwich.SR1</spring.cloud.version><lombok.version>1.18.8</lombok.version><maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

搭建服务配置中心

在spring-cloud-examples项目下创建一个子项目spring-cloud-example-config,添加Spring Cloud Config Server端的相关依赖包:关注微信公众号:互联网架构师,在后台回复:2T,可以获取我整理的架构师全套教程,都是干货。

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency></dependencies>

添加Spring Boot配置文件application.yml,配置如下:

spring:application:name: spring-cloud-example-configprofiles:active: native #启用本地配置文件cloud:config:server:native:search-locations: classpath:/configs/ #配置文件扫描目录server:port: 8000 #服务端口

启动类添加注解@EnableConfigServer通过启用Config Server服务。

@SpringBootApplication
@EnableConfigServer
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

搭建服务注册中心

在spring-cloud-examples项目下创建一个子项目spring-cloud-example-registry,在pom.xml中添加Eureka Server相关依赖包:

    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-netflix-eureka-server</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency></dependencies>

在spring-cloud-example-config配置中心项目的src/main/resource/configs目录下添加一个服务配置文件spring-cloud-example-registry.yml,配置如下:

spring:application:name: spring-cloud-example-registry# Eureka相关配置
eureka:client:register-with-eureka: false #不注册服务fetch-registry: false #不拉去服务清单serviceUrl:defaultZone: http://localhost:${server.port}/eureka/ #多个通过英文逗号分隔server:port: 8001
在spring-cloud-example-registry项目的src/main/resource/目录添加bootstrap.yml配置文件,配置如下:
spring:cloud:config:name: spring-cloud-example-registry #配置文件名称,多个通过逗号分隔uri: http://localhost:8000 #Config Server服务地址

启动类添加注解@EnableEurekaServer通过启用Eureka Server服务。

@SpringBootApplication
@EnableEurekaServer
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

搭建业务服务A

在spring-cloud-examples项目下创建一个业务服务A的子项目spring-cloud-example-biz-a,在pom.xml中添加以下依赖包:

   <dependencies><!-- Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- Eureka Client Starter --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- Config Client Starter --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency></dependencies>

在spring-cloud-example-config配置中心项目的src/main/resource/configs目录下添加一个服务配置文件spring-cloud-example-biz-a.yml,配置如下:

spring:application:name: spring-cloud-example-biz-aserver:port: 8010# Eureka相关配置
eureka:client:serviceUrl:defaultZone: http://localhost:8001/eureka/instance:lease-renewal-interval-in-seconds: 10      # 心跳时间,即服务续约间隔时间(缺省为30s)lease-expiration-duration-in-seconds: 60  # 发呆时间,即服务续约到期时间(缺省为90s)prefer-ip-address: trueinstance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}

在spring-cloud-example-biz-a项目的src/main/resource/目录添加bootstrap.yml配置文件,配置如下:

spring:cloud:config:name: spring-cloud-example-biz-a #配置文件名称,多个通过逗号分隔uri: http://localhost:8000 #Config Server服务地址

添加一个示例接口,代码参考:

@RestController
@RequestMapping("/hello")
public class HelloController {/*** 示例方法** @return*/@GetMappingpublic String sayHello() {return "Hello,This is Biz-A Service.";}
}

搭建业务服务B

参考上面业务服务A搭建另外一个业务服务B。

搭建服务网关

在spring-cloud-examples项目下创建一个业务服务A的子项目spring-cloud-example-gateway,在pom.xml中添加以下依赖包:

    <dependencies><!-- zuul --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency><!-- Eureka Client Starter --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- Config Client Starter --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency></dependencies>

在spring-cloud-example-config配置中心项目的src/main/resource/configs目录下添加一个服务配置文件spring-cloud-example-gateway.yml,配置如下:

spring:application:name: spring-cloud-example-gatewayserver:port: 8002# Eureka相关配置
eureka:client:serviceUrl:defaultZone: http://localhost:8001/eureka/instance:lease-renewal-interval-in-seconds: 10      # 心跳时间,即服务续约间隔时间(缺省为30s)lease-expiration-duration-in-seconds: 60  # 发呆时间,即服务续约到期时间(缺省为90s)prefer-ip-address: trueinstance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}

在spring-cloud-example-gateway项目的src/main/resource/目录添加bootstrap.yml配置文件,配置如下:

spring:cloud:config:name: spring-cloud-example-gateway #配置文件名称,多个通过逗号分隔uri: http://localhost:8000 #Config Server服务地址

启动类添加注解@EnableZuulProxy通过启用网关代理服务。

@SpringBootApplication
@EnableZuulProxy
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

启动示例

  • 启动顺序

spring-cloud-example-config>>spring-cloud-example-eureka>>spring-cloud-example-biz-a/spring-cloud-example-biz-b/spring-cloud-example-gateway

  • 通过网关访问服务A接口

服务A调用

  • 通过网关访问服务B接口

服务B调用

服务之间调用

在业务服务A中添加一个Feign Client Bean,参考代码如下:

@FeignClient(name = "spring-cloud-example-biz-b") # 指定服务名称
public interface RemoteService {/*** 调用服务B的hello方法** @return*/@GetMapping("/hello") #指定请求地址String sayHello();
}

业务服务A示例接口类增加call2b接口,代码如下:

@RestController
@RequestMapping("/hello")
public class HelloController {@Autowiredprivate RemoteService remoteService;/*** 示例方法** @return*/@GetMappingpublic String sayHello() {return "Hello,This is Biz-A Service.";}/*** 示例方法:调用服务B** @return*/@GetMapping(path = "/call2b")public String sayHello2B() {return remoteService.sayHello();}
}

重启业务服务A,通过调用/hello/call2b接口:

服务之间调用

下一代微服务

目前网上很多说是下一代微服务架构就是Service Mesh,Service Mesh主流框架有Linkerd和Istio,其中Istio有大厂加持所以呼声更高。Service Mesh我接触还不多,但是个人感觉并不一定能称为下一代微服务架构,可能认为是服务治理的另外一种解决方案更合适,是否能够取代当前的微服务架构还需要持续观察。

来源:https://www.cnblogs.com/jurendage/p/11331366.html

公众号后台回复【2T】有惊喜礼包!

关注微信公众号:互联网架构师,在后台回复:2T,可以获取我整理的教程,都是干货。

猜你喜欢

1、GitHub 标星 3.2w!史上最全技术人员面试手册!FackBoo发起和总结

2、如何才能成为优秀的架构师?

3、从零开始搭建创业公司后台技术栈

4、程序员一般可以从什么平台接私活?

5、37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...

6、滴滴业务中台构建实践,首次曝光

7、不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事

8、15张图看懂瞎忙和高效的区别

9、2T架构师学习资料干货分享

已经被说“烂”的微服务,到底是个什么鬼?通过拆分实战案例来带你入门。...相关推荐

  1. 微服务到底该怎么样部署呢?

    微服务应用程序可以以多种方式运行,每种方式都有不同的权衡和成本结构.适用于跨越几个服务的小型应用程序可能不足以用于大型系统. 从简单到复杂,以下是运行微服务的五种方式: 单机多进程:购买或租用服务器并 ...

  2. Java生鲜电商平台-秒杀系统微服务架构设计与源码解析实战

    Java生鲜电商平台-秒杀系统微服务架构设计与源码解析实战 Java生鲜电商平台-  什么是秒杀 通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动 比如说京东秒杀,就是一种定时定量秒杀,在规定 ...

  3. Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲

    Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台:   微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...

  4. springcloud 微服务鉴权_springcloud 微服务权限校验JWT模式获取 token 实战(十二)...

    springcloud 微服务权限校验JWT模式获取 token 实战(十二) springcloud 微服务权限校验JWT模式获取 token 实战(十二) JWT:json web token 是 ...

  5. DDD为什么能火起来?DDD 与微服务到底是啥关系!

    来源:https://www.cnblogs.com/Courage129/p/14839544.html DDD为什么能火起来? 我们先不讨论DDD的定义, 先梳理一下DDD火起来的背景, 根据我学 ...

  6. 测试一年多,上线就崩溃!微服务到底应该怎么测试?

    简介:只有了解风险,才能及时应对,保障服务高可用. 不久前,也就是11月16日,澳大利亚交易所(Australian Securities Exchange, ASX)上线了一个新的交易系统,但因为出 ...

  7. 微服务等于Spring Cloud?一文告诉你微服务到底是什么

    作者:TIM XU 原文:https://xiaoxubeii.github.io/articles/microservices-architecture-introduction/ 1 微服务初探 ...

  8. 分布式和微服务区别_分布式、集群、微服务到底有啥区别?

    点击上方"不太厉害的程序猿",选择"置顶或者星标" 你关注的就是我关心的! 来源说明:部分信息来源于csdn 概念: 集群是个物理形态,分布式是个工作方式. 1 ...

  9. 一次微服务与IoT的深度探秘与实战

    数字化经济高速发展,边缘计算.物联网.区块链等信息化技术为企业的经济环境.经济活动带来了根本性的改变.与此同时,企业最大的机遇也恰恰来自于"任何企业都在面临数字化转型".但在数字化 ...

  10. 电商平台 高并发 微服务 方案_Java生鲜电商平台-秒杀系统微服务架构设计与源码解析实战...

    Java生鲜电商平台- 什么是秒杀 通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动 比如说京东秒杀,就是一种定时定量秒杀,在规定的时间内,无论商品是否秒杀完毕,该场次的秒杀活动都会结束.这种 ...

最新文章

  1. 用人脑生成等概率随机数,困扰人类30万年的问题解决了 | 附“源代码”
  2. pandas纵向合并数据
  3. 【PAT乙级】1065 单身狗 (25 分)
  4. ios退款 怎么定位到是哪个用户_关于ios企业签名必须知道的几点
  5. nginx 配置SSL/HTTPS
  6. 设计过程中常见的 10 个小问题
  7. 不要直接对Request.Headers[If-Modified-Since]使用Convert.ToDateTime
  8. Linux压缩与解压常用命令
  9. springboot listener_看完这份springboot 全套面试提升宝典,面试不带怕的
  10. 1.6QQ拼音输入的亮点——相框
  11. svn -- 客户端+服务端的下载安装及配置
  12. Stacer ---- Linux系统优化和监测工具
  13. php英语单词大全95
  14. 为什么穷人不敢创业?
  15. mysql auto_increment 重置_如何重置MySQL中的AUTO_INCREMENT?
  16. 在spring boot中使用@WebFilter配置filter(包括排除URL)
  17. 应用 Serverless 化,让业务开发心无旁骛
  18. 如何培养员工的成就感和工作积极性
  19. 大学计算机作业互评评语简短,【同学互评评语100字】同学作业互评评语(2).doc...
  20. html里列表前的空心圆圈,如何在HTML中创建带有圆圈项目符号的无序列表?

热门文章

  1. DELPHI10.2的LINUX数据库开发环境配置
  2. maven-3.5.3通过eclipse打包问题(1)
  3. Asp.net mvc+三层架构(注册篇)
  4. 荷兰铁路在采纳敏捷和精益中的做法
  5. 安装ansible自动运维工具
  6. 5G卡位未来? 万物互联的畅想还是忧伤
  7. linux下组管理命令详解
  8. 剑指OFFER之二叉搜索树与双向链表(九度OJ1503)
  9. 获取 TUniConnection.SpecificOptions默认值和下拉框列表值
  10. Windows Server 2008 启用公共文件夹共享