一、为什么使用spring_cloud完成分布式开发

单独使用SpringBoot开发一个服务器级别的组件非常容易,但是会产生很多麻烦,我们知道分布式会开发较多的服务器级别的组件,他们之间的数据交互都是服务器级别的,并且每个服务器组件都有属于自己的配置文件,管理起来非常的不好受,所以我们使用cloud来开发

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等

当他们结合起来使用,就可以解决这些问题

二、spring_cloud分布式开发

cloud使用以下的技术来解决上面的问题
1.eureka 注册服务器组件
将服务器组件注册到一个服务器中
使用eureka导入依赖
启动类上加上 @EnableEurekaServer

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

application.yml配置如下

#服务器的端口号
server:
  port: 7000
#服务器的名字
spring:
  application:
    name: registerSys
eureka:
  instance:
    hostname: 127.0.0.1  #服务器的IP地址
  client:
    register-with-eureka: false # 是否注册自己的信息到EurekaServer,默认是true
    fetch-registry: false # 是否拉取其它服务的信息,默认是true
    serviceUrl:    #服务器向外发布的地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

2.feigin 远程调用
服务器级别组件数据交互就像调用本地的数据一样
使用feign导入依赖

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

在启动类上加上 @EnableFeignClients //feign远程调用注解

书写一个接口加上 @FeignClient(“clientone”) 注解
clientone 是服务器组件的注册名字
接口中的方法必须和要调用的方法一样

3.ribbon 负载均衡
Ribbon是一个基于HTTP和TCP的客户端负载均衡器,当我们将Ribbon和Eureka一起使用时,Ribbon会从Eureka注册中心去获取服务端列表有相同注册名的服务器组件,然后进行轮询访问以到达负载均衡的作用,这个功能封装在eureka依赖中所以导入依赖和上面的eureka一样

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

所以注册到注册服务器的服务器的启动类加上注解
@EnableEurekaClient //注册客户端,负载均衡rabbon

application.yml配置如下

#服务器的端口号
server:
  port: 7001
#服务器的名字
spring:
  application:
    name: clientone
eureka:
  instance:
    hostname: 127.0.0.1  #服务器的IP地址
  client:
    serviceUrl:    #服务器向外发布的地址
      defaultZone: http://127.0.0.1:7000/eureka/

4.hystrix 熔断 防止链式反应
导入的依赖

<!--熔断-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
启动类上的注解@EnableCircuitBreaker //熔断

调用方法的类 详细看里面的注释

@Service
public class NomalService {
    @Autowired
    private FeignService feignService;
    //当这个服务调用失败时调用hellofailred
    @HystrixCommand(fallbackMethod = "hellofailred")
    public String hello(){
        return feignService.info();
    }
    //    当上面的访问服务器出错就会访问下面的方法
    public String hellofailred(){
        return "当前服务器不能访问";
    }
}

5.config 配置 解决配置管理问题
这儿要注意到依赖导入问题,配置服务导入的依赖和客户端导入的依赖是不同的
配置服务器导入的依赖

<!--配置服务-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

客户端导入的依赖

<!--配置客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

使用config配置服务器后
将客户端的application.yml改为bootstrap.yml
为什么?因为bootstrap.yml的优先级要高于application.yml

然后config配置服务器这边的配置文件如下,configfile文件下的配置文件为其他客户端服务器的配置文件,里面的配置还是和以前一样写,但是客户端服务器下的bootstrap.yml配置文件要指向配置服务器

springcloud 项目源码 springcloud开发_服务器


bootstrap.yml配置如下

spring:
  application:
    name: clientone
  cloud:
    config:
      profile: dev      #后缀
      uri: http://127.0.0.1:8888/ #配置服务器的地址

config服务器配置如下
aplication.yml

spring:
  profiles:
    active: native  #本地的

application-native.yml

server:
  port: 8888
spring:
  application:
    name: configServer  #注册服务器名
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/configfile/ #搜索位置(各个配置文件的存放处)

6.API 网关 使用zuul (过滤和路由)
导入的依赖

<!--网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

启动类加的注解 @EnableZuulProxy //网关代理

过滤器类的方法

@Component
public class MyFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";// 前置过滤器
//        pre:可以在请求被路由之前调用
//        route:在路由请求时候被调用
//        post:在route和error过滤器之后被调用
//        error:处理请求时发生错误时被调用
    }
    @Override
    public int filterOrder() {
        return 0;//优先级为0,数字越大,优先级越低
    }
    @Override
    public boolean shouldFilter() {
        return true;//是否过滤
    }
    @Override
    public Object run() throws ZuulException {
        System.out.println("进入过滤器");
        return null;
    }
}