微服务架构理论(摘自简书,作者centychen)

一、概念

1、单体应用

        什么是微服务?

        在了解微服务之前,我们需要先知道什么叫单体应用 -- 

         在没有提出微服务的概念之前, 一个软件应用,往往会将所有的功能都开发和打包在一起,那个时候的B/S架构往往是这样的:

B/S


        这种架构,在以前就容易出现一个问题:当用户访问量变大,一台服务器无法支撑,这个时候怎么办?加服务器加负载均衡,然后架构就变成这样:

B/S+负载均衡


        后来,发现如果将静态文件独立出来,通过CDN等手段进行加速,可以提升应用的整体响应,单体架构就变成了前后端分离式应用:

B/S+负载均衡+前后端分离


        然而此时,其实架构依然是单体架构,只是在部署等方面,进行了优化,但仍然避免不了单体架构的缺点:

·代码臃肿,应用启动时间长,有些应用甚至可以大于1G;

·回归测试周期长,修复一个小小bug可能需要对所有关键业务进行全面测试;

·应用容错性差,可能一个小小功能的程序错误会导致整个应用宕机;

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

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

2、微服务应用

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

        撇开架构不说,通俗的讲,作者认为微服务应该具有以下特征:
1)单一职责。每个微服务都是单一职责的,一个微服务解决一个业务问题;

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

        

        而从专业角度论述:

1)微服务是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间应该互相协调、互相配合,为用户提供最终价值。

2)每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。

3)每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。

4)应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

3、微服务典型架构

        对于微服务架构,其本身核心,是为了解决应用微服务化后的服务治理问题。

3.1服务注册中心

        应用服务化后,首先遇到的第一个问题,是服务发现问题。一个微服务,如何去发现其他的微服务呢?

        最简单的方式,是每个微服务里面,配置其他的微服务地址。但是显然,当微服务的数量众多的时候,这个方式明显不符合现实。此时,就需要使用到微服务架构中的一个组件 - 服务注册中心

        我们可以所有的服务都注册到服务注册中心,同时也可以从服务注册中心获取当前可用的服务清单:

服务注册中心

3.2配置中心

        当解决完服务发现问题后,接着需要解决微服务分布式部署带来的第二个问题:服务配置管理的问题。

        当服务注册数量超过一定程度之后,如果需要在每个服务里分别维护每一个服务的配置文件,运维人员估计要哭了。此时,就需要使用到微服务架构里面的第二个重要的组件:配置中心。微服务架构就变成了这样:

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

典型微服务架构

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

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

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

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

·服务调用链跟踪等。

4、微服务框架

        目前国内企业使用的微服务框架主要是Spring Cloud和Dubbo(或者DubboX),但是Dubbo那两年的停更严重打击了开发人员对它的信心,SpringCloud已经逐渐成为主流。

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

Spring Cloud常用组件       

5、搭建典型微服务架构

5.1建立父项目 spring-cloud-examples

      首先,创建一个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>

6、搭建服务配置中心

       

6.1建立子项目并添加依赖

        在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>

6.2添加关联配置文件

        添加SpringBoot配置文件application.yml,具体如下:

spring:
  application:
    name: spring-cloud-example-config
  profiles:
    active: native #启用本地配置文件
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/configs/ #配置文件扫描目录

server:
  port: 8000 #服务端口

6.3启动类添加注解

  启动类添加注解:@EnableConfigServer ,允许通过启用ConfigServer服务

@SpringBootApplication
@EnableConfigServer
public class Application {

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

7、搭建服务注册中心

7.1建立子项目并添加依赖:       

在spring-cloud-example项目下,创建一个子项目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>

7.2建立关联配置文件      

 a、 在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

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

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

7.3启动类添加注解

        在项目启动类中,添加注解@EnableEurekaServer通过启用Eureka Server服务

@SpringBootApplication
@EnableEurekaServer
public class Application {

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

8、搭建业务服务A

8.1建立子项目并添加依赖:

  • 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>

8.2建立关联配置文件

  • 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.";
    }
}

9、搭建业务服务B

        业务服务B的搭建可以直接参考A执行搭建,换个不同名称即可。这里不再描述。

10、搭建服务网关

10.1建立子项目并添加依赖:

        在父项目srping-cloud-example项目下,创建一个子项目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>

10.2建立关联配置文件:

       1) 在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}}

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

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

10.3启动类添加注解:

        在本项目启动类中添加@EnableZuulProxy注解,通过启用网关代理服务:

@SpringBootApplication
@EnableZuulProxy
public class Application {

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

11、启动示例:

11.1 启动顺序:

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

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

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

12、服务之间调用

        1)在业务服务A中添加一个Fetign Client Bean,参考代码:

@FeignClient(name = "spring-cloud-example-biz-b") # 指定服务名称
public interface RemoteService {

    /**
     * 调用服务B的hello方法
     *
     * @return
     */
    @GetMapping("/hello") #指定请求地址
    String sayHello();
}

       2) 业务服务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();
    }
}

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

13、简书坐着的示例代码:

14、下一代微服务

        目前网上很多说是下一代微服务架构就是Service Mesh,Service Mesh主流框架有Linkerd和Istio,其中Istio有大厂加持所以呼声更高。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud是一个基于Spring Boot的微服务框架,该框架主要用于快速搭建和管理分布式系统中的微服务架构。下面我将以简书为例,简要介绍Spring Cloud微服务框架的搭建过程。 1. 创建Spring Boot项目:首先,我们需要创建一个Spring Boot项目作为微服务的基础。可以通过Spring Initializr来快速创建一个Spring Boot项目,选择相应的依赖,如Spring Web、Eureka Discovery等。 2. 配置服务注册中心:在Spring Cloud中,Eureka被广泛用作服务注册和发现的中心。在项目的配置文件中,添加Eureka的配置,指定注册中心的地址。 3. 创建微服务:在项目中,创建需要的微服务模块,例如用户服务、文章服务、评论服务等。每个微服务都是一个独立的Spring Boot应用,可以独立运行和部署。 4. 配置服务间的通信:微服务之间需要进行通信,可以使用Spring Cloud提供的Feign或RestTemplate来实现。在服务之间的API接口中,通过注解的方式定义接口,使得服务之间的调用更加简洁。 5. 配置服务网关:为了统一管理微服务接口的访问和安全,可以使用Spring Cloud Gateway作为服务网关。通过配置路由规则和过滤器,对外暴露统一的API接口。 6. 配置服务熔断与降级:在分布式系统中,不可避免地会遇到服务不可用或故障的情况。可以使用Spring Cloud提供的Hystrix进行熔断和降级处理,保证系统的稳定性。 7. 配置服务监控与追踪:为了对微服务进行监控和追踪,可以使用Spring Cloud提供的Actuator和Sleuth。Actuator可以暴露微服务的运行指标,Sleuth可以追踪微服务之间的调用链路。 8. 部署与管理:最后,将各个微服务打包成独立的Docker镜像,并通过Docker容器技术进行部署。使用Kubernetes、Docker Swarm或者Mesos等容器管理工具,可以更好地管理和扩展微服务集群。 以上是简要的Spring Cloud微服务框架搭建过程,通过这个框架,可以实现高可用、弹性、可伸缩的分布式系统架构,帮助开发者更快速地构建和管理微服务应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值