微服务之SpringCloud

目录

 

一.系统架构演变、微服务介绍

二、初始SpringCloud

三、微服务场景模拟

1、认识Eureka  注册中心

2、负载均衡Ribbon

3、Hystrix 熔断器

4、Feign伪装

5、Zuul网关


github代码:https://github.com/XinCongming/SpringCloud

一.系统架构演变、微服务介绍

1、集中式架构:当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。

2、垂直拆分当访问量逐渐增大,单一应用无法满足需求,为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆

3、分布式服务当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。

4、服务治理(SOA):当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键

5、微服务:微服务是一种架构风格,即将单体应用划分为小型的服务单元,微服务之间使用 HTTP 的 API 进行资源访问与操作。

微服务架构的演变更像是一个公司的发展过程,从最开始的小公司,到后来的大集团。大集团可拆分出多个子公司,每个子公司的都有自己独立的业务、员工,各自发展,互不影响,合起来则是威力无穷。

微服务架构的优势

1)服务的独立部署:每个服务都是一个独立的项目,可以独立部署,不依赖于其他服务,耦合性低。

2)服务的快速启动:拆分之后服务启动的速度必然要比拆分之前快很多,因为依赖的库少了,代码量也少了。

3)更加适合敏捷开发:敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行。服务拆分可以快速发布新版本,修改哪个服务只需要发布对应的服务即可,不用整体重新发布。

4)职责专一,由专门的团队负责专门的服务:业务发展迅速时,研发人员也会越来越多,每个团队可以负责对应的业务线,服务的拆分有利于团队之间的分工。

5)服务可以动态按需扩容:当某个服务的访问量较大时,我们只需要将这个服务扩容即可。

6)代码的复用:每个服务都提供 REST API,所有的基础服务都必须抽出来,很多的底层实现都可以以接口方式提供。

微服务结构图:

二、初始SpringCloud

Spring最擅长的就是集成,把世界上最好的框架拿过来,集成到自己的项目中。SpringCloud也是一样,它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能。其主要涉及的组件包括:

netflflix、Eureka:注册中心、Zuul:服务网关、Ribbon:负载均衡、Feign:服务调用、Hystix:熔断器等等

三、微服务场景模拟

1、认识Eureka  注册中心

Eureka负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。同时,服务提供方与Eureka之间通过“心跳”机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从列表中剔除。这样就实现了服务的自动注册、发现、状态监控。

基础架构

Eureka架构中的三个核心角色:

  • 服务注册中心:Eureka的服务端应用,提供服务注册和发现功能,对应项目eureka-server
  • 服务提供者:提供服务的应用,可以是SpringBoot应用,也可以是其他任意技术实现,只要对外提供的是Rest风格服务即可,本例中就是我们实现的user-service
  • 服务消费者:消费应用从注册中心获取服务列表,从而得知每个服务方的信息,知道去哪里调用服务方。本例是consumer-service

高可用Eureka Server

Eureka Server即服务的注册中心,它也可以是一个集群。

服务同步:多个Eureka Server之间也会互相注册为服,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,客户端访问到Eureka Server集群中的任意一个节点,都可以拉取到完整的服务列表信息。

#application.yml相关配置信息
server:
  port: 10086 # 端口
eureka:          #eureka服务注册
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka  #高可用
  instance:
    prefer-ip-address: true #可以将IP注册到Eureka Server上,如果不配置就是机器的主机名
    ip-address: 127.0.0.1
spring:
  application:
    name: eureka-server #服务名称,不写否则就是UNKNOWN

#启动类声明
@EnableEurekaServer // 声明这个应用是一个EurekaServer

复制一个EurekaApplication2,在两个启动的配置VM Options中分别添加:

-Dserver.port=10086 -Deureka.client.serviceurl.defaultZone=http://localhost:10086/eureka,http://localhost:10087/eureka

-Dserver.port=10087 -Deureka.client.serviceurl.defaultZone=http://localhost:10086/eureka,http://localhost:10087/eureka

服务提供者 user-service

服务提供者要向EurekaServer注册服务,并且完成服务续约(心跳机制)等工作。

#eureka配置信息、注册地址  application.yml
spring:
  datasource:
    username: root
    url: jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    password: zxc123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:   #应用名称
    name: user-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
  instance:
    prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

#启动类加一个注解
@EnableDiscoveryClient // 开启EurekaClient功能

服务消费者 consumer-service

#application.yml配置信息
spring:
  application:
    name: consumer-service   #服务名称
#向eureka进行注册
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

#启动类加一个注解
@EnableDiscoveryClient // 开启EurekaClient功能

2、负载均衡Ribbon

(1)开启两个服务提供者实例

user-service中,复制一个启动类UserApplication2,并改配置:

(2)开启负载均衡Ribbon

consumer-service中,添加依赖:

        <!--负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>

restTemplate添加@LoadBalanced     

//使用HttpClient 或者urlConnection进行远程访问
    @Bean
    @LoadBalanced     //ribbon负载均衡
    public RestTemplate restTemplate(){return new RestTemplate();}
    @Autowired
    private RestTemplate restTemplate;

    public User queryById(long id) {
   restTemplate.getForObject("http://"+host+":"+port+"/user/"+id,User.class);

//利用eureka通过服务应用名称获取提供服务的host+port   user-service对应提供服务端配置文件中application name
        return
                restTemplate.getForObject("http://user-service/user/"+id,User.class);
    }

Ribbon会自动实现负载均衡,默认是简单的轮询策略

3、Hystrix 熔断器

容错处理是指软件运行时,能对由非正常因素引起的运行错误给出适当的处理或信息提示,使软件运行正常结束。

在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。

雪崩问题:微服务中,服务间调用关系错综复杂,一个请求,可能需要调用多个微服务接口才能实现,会形成非常错综复杂的调用链路。如果一个微服务发生异常,求情阻塞,用户不会得到响应,则tomcat的这个线程不会释放,于是越来越多的用户请求来,越来越多的线程阻塞,服务器支持的线程和并发数有限,请求会一直阻塞,会导致服务器资源耗尽,从而导致其他服务都不能用,形成雪崩效应。

Hystrix解决雪崩的问题有两个方法:1、线程隔离、服务降级   2、服务熔断

(1)线程隔离、服务降级

Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,默认不采用排队,加速失败判定时间

案例:consumer-service中,添加依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>

开启熔断:consumer-service的启动类添加 @EnableCircuitBreaker 注解或者 @EnableHystrix

consumer-service加入注解后,如果访问超时等出现问题,会执行失败回滚处理函数,详情代码见github

(2)服务熔断   熔断器,也较断路器

为了方便测试熔断器,先修改配置参数

 @HystrixCommand(commandProperties = {  //设置超时时间3000  只对此方法生效
//            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000"), //超时
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),  //最小请求次数,默认20
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//休眠时长,默认5000
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60")//失败请求最小占比,默认50%
    })

然后访问十遍http://localhost:8003/cs/consumer/hystrix/2,这样熔断器的状态机就会open,在10秒内访问http://localhost:8003/cs/consumer/hystrix/1也是执行错误回滚函数,十秒后正常访问。

4、Feign伪装

Feign可以把Rest请求进行隐藏,伪装成类似SpringMVC的Controller一样。你不用自己拼接url,拼接参数等操作,全部交给Feign

(1)添加依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

(2)feign客户端

@FeignClient("user-service")   //声明这是一个feign客户端
public interface userClient {

    @GetMapping("/user/{id}")
    User queryUserById(@PathVariable("id") Long id);
}

启动类:

@EnableFeignClients   //开启Feign

controller中调用

    @Autowired
    private userClient userClient;

    @GetMapping("{id}")
    public User queryById(@PathVariable("id") Long id) {
        return userClient.queryUserById(id);           //feign
    }

(3)feign中同时支持了熔断和负载均衡,所以对应的hystrix依赖也可以完全去掉

(4)Feign支持请求和响应进行GZIP压缩,以减少通信过程中的性能消耗

feign:
  compression:
    request:
      enabled: true   #开启请求压缩
      mime-types: text/html,application/json   #设置压缩的数据类型,默认也是如此
      min-request-size: 2048  #设置触发压缩额最下限,默认也是如此
    response:
      enabled: true   #开启响应压缩

5、Zuul网关

以上就是实现springcloud微服务的基本架构,如下:
 

加入zuul网关后的架构:

(1)快速入门

新建module,加入依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>

启动类加注解  @EnableZuulProxy

#配置文件
spring:
  application:
    name: api-gateway   #指定服务名
zuul:
  routes:
    hehe:  #路由id,随意
      path: /user-service/**  #映射路径
      url: http://127.0.0.1:8081  #映射路径对应的实际url地址

启动访问http://localhost:10010/user-service/user/1

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值