springCloud与微服务构建

1SpringCloud与微服务构建

1、创建一个maven父工程springboot-parent

2、修改pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.forezp</groupId>
    <artifactId>springboot_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencyManagement>
    <dependencies>
        <!--Web相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>1.5.3.RELEASE</version>
        </dependency>
        <!--测试相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>1.5.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.4.0</version>
            <scope>test</scope>
        </dependency>
        <!--servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>3.0-alpha-1</version>
        </dependency>
        <!--EurekaServer相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.6.RELEASE</version>
        </dependency>
        <!--Ribbon 相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>1.4.3.RELEASE</version>
        </dependency>
        <!--Feign的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.3.6.RELEASE</version>
        </dependency>
        <!--Hystrix 相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>1.5.3.RELEASE</version>
        </dependency>
        <!--Zuul 相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.3.6.RELEASE</version>
        </dependency>
        <!--其他依赖-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
    </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2、创建一个子工程作为服务的注册中心(springboot-eureka)

2.1修改springboot-eureka工程的pom文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--EurekaServer相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
        </dependency>
    </dependencies>

2.2修改springboot-eureka工程的配置文件application.yml

server:
  port: 8751
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false  #防止自己注册自己
    fetch-registry: false        #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone:
        http://${eureka.instance.hostname}:${server.port}/eureka/

2.3在启动类上加@EnableEurekaServer,开启eurekaServer功能。

 

2.4启动项目

浏览器访问http://localhost:8751/

注:Instance currently registered with Eureka这一项没有任何注册的实例,这是正常,因为还没有Eureka Client客户端向注册中心Eureka Server 注册实例 

3创建一个springboot工程(springboot-client)

3.1修改配置文件application.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8751/eureka/  #注册中心的地址
server:
  port: 8752
spring:
  application:
    name: springboot-client  #注意服务名称不能用下划线

3.2修改pom文件

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--EurekaServer相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </dependency>
    </dependencies>

启动类上加@EnableEurekaClient 注解

启动程序再次访问http://localhost:8751/

可以看到Eureka Client已经向Eureka Service 注册了。

4构建高可用Eureka Server集群

1首先修改eureka-server 的配置文件application.yml,采用多profile的格式,定义两个profile配置文件peer1和peer2,端口分别为8752和8753,8752和8753互相注册

spring:
  profiles:
    active: peer1
---
spring:
  profiles: peer1
server:
  port: 8752
eureka:
  client:
    service-url:
      defaultZone:
        http://127.0.0.1:8753/eureka/
---
spring:
  profiles: peer2
server:
  port: 8753
eureka:
  client:
    service-url:
      defaultZone:
        http://127.0.0.1:8752/eureka/

2启动eureka-server

java -jar springboot_eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1 

java -jar springboot_eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer12

3修改springboot-client的配置文件,端口为8761,并向端口为8752的的eureka-server注册中心注册,代码如下

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8752/eureka/ 
server:
  port: 8761
spring:
  application:
    name: springboot_client

启动springboot-client工程,访问http://localhost:8752 可以发现springboot-client已经向8752注册,并且在DS Replicas中显示8753节点

此时springboot-client的配置文件中并没有指定8753节点,访问http://localhost:8753 可以看到eureka-client也向8753节点注册了,两个节点已经实现了信息同步。

5、负载均衡Ribbon

负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两中方式,一种是独立进程单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如Nginx。另一种是将负载均衡逻辑已代码的方式封装到服务消费者的客户端上,服务消费者的客户端维护了一份服务提供者的信息列表,有了信息列表,通过负载均衡策略,将请求分摊给多个服务提供者,从而达到负载均衡的目的。Ribbon就属于第二中方式,将负载均衡逻辑封装到客户端中,并且运行在客户端的进程里,在SpringCloud构建的微服务系统中,Ribbon作为服务消费者的负载均衡器,有两种使用方式,一种是和RestTemplate的结合,另一种是和Feign相结合,并且Feign已经默认集成了Ribbon.

5.1使用RestTemplate和Ribbon消费服务

修改上面创建的springboot-client工程,使其作为服务提供者,并且提供一个 “/hi” 接口,启动两个实例。

新建两个配置文件application-peer1.yml和application-peer2.yml

application-peer1.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8751/eureka/  
server:
  port: 8761
spring:
  application:
    name: springboot-client

application-peer2.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8751/eureka/
server:
  port: 8762
spring:
  application:
    name: springboot-client

HiController.java

@RestController
public class HiController {
    @Value("${server.port}")
    private  String port;
    @RequestMapping("/hi")
    public String hi(String name){
        return name+"访问端口与为"+port+"的服务";
    }
}

启动两个实例。

5.2新建springboot工程(spirngboot-resttemplate-client)

作为服务的消费者。并编写一个接口,在该接口内部调用springboot-client中的"/hi" 接口,并做到轮流访问两个实例,这时就需要将RestTemplate和Ribbon相结合进行负载均衡。

那么如何将restTemplate和Ribbon相结合呢?只需要向Ioc容器中注入一个bean,并在这个bean上加上一个@LoadBalanced注解即可。

修改pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--EurekaServer相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.archaius</groupId>
            <artifactId>archaius-core</artifactId>
            <version>0.7.6</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

修改配置文件 application.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8751/eureka/
server:
  port: 8771
spring:
  application:
    name: spirngboot-resttemplate-client

新建一个RibbonConfig.java的类

@Configuration
public class RibbonConfig {
    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return  new RestTemplate();
    }
}

新建一个RibbonService.java

@Service
public class RibbonService {
    @Autowired
    private RestTemplate restTemplate;
    public String hi(String name){
       return restTemplate.getForObject("http://springboot-client/hi?name="+name,String.class);
    }
}

新建RibbonController

@RestController
public class RibbonController {
    @Autowired
    private RibbonService ribbonService;
    @GetMapping("/ribbonhi")
    public String ribbonhi(String name){
        return  ribbonService.hi(name);
    }
}

启动工程浏览器访问 http://localhost:8771/ribbonhi?name=张三,可以看到结果是轮流访问了8761和8762两个实例

6 声明式调用Feign

负载均衡Ribbon的另一种使用方式是和Feign像结合,通过Feign来远程调度其他服务.

创建一个springboot工程springboot-feign-client,修改pom文件如下:

<!--web相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--Feign的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <!--Eureka相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        

修改application.yml配置文件

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8751/eureka/
server:
  port: 8781
spring:
  application:
    name: springboot-feign-client
feign:
  hystrix:
    enabled: true

创建一个接口和实现类,代码如下:

@FeignClient(value = "springboot-client")
public interface EurekaFeignClient {
    @GetMapping("/hi")
    public String SayHiFromSpringbootClient(@RequestParam(value = "name") String name);
}
@Service
public class FeignService {
    @Autowired
    private EurekaFeignClient eurekaFeignClient;
    public String sayHi(String name){
        return  eurekaFeignClient.SayHiFromSpringbootClient(name);
    }
}

启动类:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class SpringbootFeignClientApplication {

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

}

浏览器访问http://localhost:8781/hi?name=zhangsan

可以看到Feign-client 远程调用了springboot-client 服务,轮流访问两个实例,具有负载均衡能力,并且Feign的依赖中默认引入了Ribbon和Hystrix,具有负载军均衡和熔断器的依赖。

7、熔断器Hystrix

在分布式系统中,服务与服务的依赖关系错综复杂,一种不可避免的情况就是某些服务出现故障,导致依赖于他们的其他服务出现远程调度的线程阻塞,最终导致整个服务的线程资源消耗殆尽,最后整个服务不可用,即雪崩效应。

7.1在restTemplate 和 Ribbon 上使用熔断器

修改上面新建的springboot-client工程,首先在pom.xml文件加入Hystrix的起步依赖

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

然后在启动类上加入@EnableHystrix注解,开启Hystrix的熔断器功能,代码如下:

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

修改RibbonService代码,在hi()方法上加上@HystrixCommand注解,有了@HystrixCommand注解,这hi()方法就有了熔断器的功能,其中fallbackMethod为处理回退逻辑的方法,这里要注意,fallbackMethod指定的方法的参数要和@HystrixCommond修饰的方法的参数一致,代码如下:

@Service
public class RibbonService {
    @Autowired
    private RestTemplate restTemplate;
    @HystrixCommand(fallbackMethod = "hiError")
    public String hi(String name){
       return restTemplate.getForObject("http://springboot-client/hi?name="+name,String.class);
    }

    public String hiError(String name){
        return name + "调用服务异常,熔断器启动";
    }
}

启动程序,当Eureka Client服务启动的时,RibbonService能够正常调用,当关闭Eureka Client服务时,再次访问,就会快速执行hiError()方法。

6.2在Feign上使用熔断器。

首先修改springboot-feign-client 工程 application.yml配置文件,配置开启Hystrix的功能。

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8751/eureka/
server:
  port: 8781
spring:
  application:
    name: springboot-feign-client
feign:
  hystrix:
    enabled: true

pom.xml添加相关依赖

<!--hystrix依赖-->
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
 </dependency>

修改EurekaFeignClient接口

@FeignClient(value = "springboot-client",fallback = Hystrix.class)
public interface EurekaFeignClient {
    @GetMapping("/hi")
    public String SayHiFromSpringbootClient(@RequestParam(value = "name") String name);
}

新增熔断器处理类Hystrix.java

@Component
public class Hystrix implements EurekaFeignClient {
    @Override
    public String SayHiFromSpringbootClient(String name) {
        return name+"Feign服务调用异常,熔断器启动";
    }
}

启动程序,当Eureka Client服务关闭时,再次访问时会快速进入熔断器。

8、路由网关Spring Cloud Zuul

8.1.为什么使用zuul?

  • zuul,Ribbon,Eureka相结合,可以实现智能路由和负载均衡的功能,Zuul能够将请求流量按某种策略分发到集群状态的多个服务实例。
  • 网关将所有服务的API接口统一聚合,并统一对外暴露,外界系统调用API借口时,都是由网关对外暴露的API接口,外界系统不需要知道微服务系统中服务相互调用的复杂性,防止被外界直接调用,导致服务的敏感信息对外暴露。
  • 网关服务可以做用户身份认证和权限认证
  • 网关可以实时监控功能,实时日志输出,对请求进行记录。

8.2、Zuul的工作原理

  • zuul是通过servlet实现的,Zuul通过自定义的ZuulServlet(类似于SpringMvc 的 DispatchServlet)对请求进行控制,Zuul的核心是一系列的过滤器,可以在http请求的发起和响应返回期间执行一系列的过滤器。Zuul一共包括四种过滤器:
  • PRE过滤器:它是在请求路由到具体的服务之前执行的,这种类型的过滤器可以用作安全验证,例如身份验证,参数验证等。
  • ROUTING过滤器:它用于将请求路由到具体的微服务实例。默认使用http Client 进行网络请求。
  • POST过滤器:它是在请求已被路由到微服务之后执行的。一般情况先,用作收集统计信息、指标、以及将相应传输到客户端。
  • ERROR过滤器:它是在其他过滤器发生错误时执行的。

Zuul采取了动态读取、编译运行这些过滤器,过滤器之间不能直接互相通信,而是通过RequestContext来共享数据,每个请求都会创建一个RequestContext对象。Zuul过滤器有几个关键特性

Type(类型):Zuul过滤器的类型,这个类型决定了过滤器在哪个阶段起作用,例如 PRE、POST

Execution Order(执行顺序):规定了过滤器的执行顺序,Order值越小,越优先执行

Criteria(标准):Filter执行所需要的条件

Action(行动,也就是逻辑代码):如果符合执行条件,则执行逻辑代码。

8.3、搭建Zuul服务

 新建一个springboot 工程springboot-zuul并引入先关依赖

    <dependencies>
        <!--springboot依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--eureka 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <!--Zuul相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
    </dependencies>

在启动类SpringbootZuulApplication添加@EnableZuulProxy注解,开启Zuul的功能

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

修改配置文件

以hiapi开头的请求都转发到spring-client服务中,以feignapi开头的都转发到springboot-feign-client服务中,其中的“hiapi”和“feignapi”是自己定义的,下面要包含path和serviceId属性

server:
  port: 8791
spring:
  application:
    name: springboot-zuul
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8751/eureka/
zuul:
  routes:
    hiapi:
      path: /hiapi/**
      serviceId : springboot-client
    feignapi:
      path: /feignapi/**
      serviceId: springboot-feign-client

8.4在Zuul上配置熔断器

在Zuul中实现熔断功能需要实现ZuulFallbackProvider的接口,实现该接口有两个方法,一个是getRoute()方法,用于指定熔断功能应用于哪些路由的服务,另一个方法fallBackResponse()为进入熔断式执行的逻辑,例如:如果要实现一个针对springboog-client服务的熔断功能,只需新建一个java类实现ZuulFallbackPorvider接口,代码如下:

@Component
public class MyFallbackProvider implements ZuulFallbackProvider {
    @Override
    public String getRoute() {
        // "*" 代表对所有的服务都加熔断功能,也可以指定具体的服务名称,代表只对改服务加熔断。
        return "*";
    }

    @Override
    public ClientHttpResponse fallbackResponse() {
        ClientHttpResponse clientHttpResponse = new ClientHttpResponse() {
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }

            @Override
            public InputStream getBody() throws IOException {
                String returnMsg = "网关熔断器启动。。。。";
                ByteArrayInputStream inputStream = new ByteArrayInputStream(returnMsg.getBytes());
                return inputStream;
            }

            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }

            @Override
            public String getStatusText() throws IOException {
                return "ok";
            }

            @Override
            public void close() {

            }
        };
        return clientHttpResponse;
    }
}

8.5在Zuul中使用自定义过滤器

在Zuul中实现自定义过滤器很简单,只需要继承ZuulFilter,并实现ZuulFilter中的抽象方法,其中filterType()为过滤器的类型(有4种类型“pre” "post" "routing" "error"),filterOrder()为过滤器的顺序,它是一个int值,值越小,越早执行该过滤器,shouldFilter()表示该过滤器是否过滤逻辑,如果为true则执行run()方法,如果为false则不执行run()方法,run()方法中写具体的过滤逻辑。

@Component
public class MyFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext cxt = RequestContext.getCurrentContext();
        HttpServletRequest request = cxt.getRequest();
        String name = request.getParameter("name");
        System.out.print("执行过滤器,接收参数为name = " + name);
        return null;
    }
}

9、分布式配置中心spring cloud config

9.1、config Server从本地读取配置文件

configServer 可以从本地读取配置文件,也可以从远程git仓库读取配置文件,从本地读取配置文件是指将所有的配置文件统一写在一个Config Server目录下,Config Server暴露http api接口,Config Client 通过调用Config Server的http api接口来获取配置文件。

新建一个Config Server 工程(springboot-config-server)

修改pom.xml文件,添加config Server依赖

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
</dependency>

在启动类上加上@EnableConfigServer注解,开启config Server功能。

修改配置文件application.yml,通过spring.profiles.active=native配置config Server 从本地读取配置,读取配置的路径为classpath下的share目录。

spring:
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/shared
  profiles:
    active: native
  application:
    name: springboot-config-server
server:
  port: 8792

在share目录下新建一个spring-config-client-dev.yml的配置文件

新建一个Config Client 工程(springboot-config-client)

pom.xml文件引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

将application.yml名称改为bootstrap.yml,bootstrap相对于application具有优先的执行顺序,bootstrap.yml代码如下

spring:
  application:
    name: springboot-config-client
  cloud:
    config:
      uri: http://localhost:8792   #读取配置文件的地址
      fail-fast: true  #如果没有读取成功则执行快速失败
  profiles:
    active: dev    #配置文件中{spring.application.name} 和 {spring.profiles.active} 两者以"-"相连,构成了向config Server读取的配置文件名

启动springboot-config-client工程,可以看到工程加载了配置中心中的配置文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值