Java fresh business platform - micro-Services and services split architecture combat

Java fresh business platform - micro-Services and services split architecture combat

The beginning of the software industry into the era of a monomer or application, before and after the end of the separation of the concepts are still not commonplace, developed when the need to spend a lot of time in the "strong" JSP above, when SOA is considered a new technology. Now, micro-services have become very popular, which have their own Internet products do not say it is a micro-service architecture?

However, understanding the micro-services are not the same for everyone, This article is my understanding of the micro-chat service and how to set up the classic micro-service architecture, aims to sort out some of their own ideas, if there are different views welcome to correct me!

What is micro-services

First, what is a micro-services?

Single application

In contrast, to understand what is micro-services, you can understand what is the first single application, there is no concept of micro-services "ancient" era, a software application, often will use all features are developed and packaged together, time of a B / S architecture is often such applications:


 
B/S

However, when a user accesses a server becomes larger cause can not support how to do it? Plus plus server load balancing, architecture becomes the case:


 
B / S + Load Balancing

Later found to separate out static files, CDN accelerated by other means, can enhance the overall application of the corresponding monomers application architecture becomes:


 
B / S + separated front and rear ends

Infrastructure 3 above are still single application, but has been optimized for deployment, we can not avoid the fundamental defect of single applications:

  • Code bloat, the application starts a long time; (Code project more than 1G have!)
  • Regression test cycle is long, a small bug fix may need to perform regression testing for all critical business.
  • Poor application fault tolerance, the program features a small error can cause the entire system downtime;
  • Telescopic difficulties, the entire application can only be extended when the monomer extend application performance, resulting in waste of computing resources.
  • Development collaboration difficult, a large-scale applications, it may be dozens or even hundreds of developers, we are maintaining a set of code words, a sharp increase in the complexity of the code merge.

Micro Services

I think the evolution of any technology are tracked any new technologies are designed to address the needs of the existing technology can not be resolved, therefore, is the emergence of micro-services monomer because the original application architecture has been unable to meet current Internet products technology needs.

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

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

  • 单一职责的。一个微服务应该都是单一职责的,这才是“微”的体现,一个微服务解决一个业务问题(注意是一个业务问题而不是一个接口)。
  • 面向服务的。将自己的业务能力封装并对外提供服务,这是继承SOA的核心思想,一个微服务本身也可能使用到其它微服务的能力。
    我觉得满足以上两点就可以认为典型的微服务。

微服务典型架构

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

应用微服务化之后,首先遇到的第一个问题就是服务发现问题,一个微服务如何发现其他微服务呢?最简单的方式就是每个微服务里面配置其他微服务的地址,但是当微服务数量众多的时候,这样做明显不现实。所以需要使用到微服务架构中的一个最重要的组件:服务注册中心,所有服务都注册到服务注册中心,同时也可以从服务注册中心获取当前可用的服务清单:

 
服务注册中心

 

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

 
配置中心

以上应用内部的服务治理,当客户端或外部应用调用服务的时候怎么处理呢?服务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端的相关依赖包:
<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-config
  profiles:
    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-a

server:
  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: true instance-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 */ @GetMapping public 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-gateway

server:
  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: true instance-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 { @Autowired private RemoteService remoteService; /** * 示例方法 * * @return */ @GetMapping public 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我接触还不多,但是个人感觉并不一定能称为下一代微服务架构,可能认为是服务治理的另外一种解决方案更合适,是否能够取代当前的微服务架构还需要持续观察。

Guess you like

Origin www.cnblogs.com/jurendage/p/11331366.html