SpringCloud系列

SpringCloud系列

以下内容,均在搭建 lemon 项目时,收集和写下的一些内容,如有错误欢迎指正>>>

实际中应用及推荐文章

推荐文章:https://blog.csdn.net/zrl0506/article/details/80165477

推荐文章:https://blog.csdn.net/qq_37170583/article/details/80704904

SpringCloud和SpringBoot对应版本

官方文档:http://spring.io/projects/spring-cloud(一切始于官方文档)

Table1

SpringCloudSpringBoot
Greenwich2.1.X
Finchley2.0.X
Edgware1.5.x
Dalston1.5.x

Table2

ComponentEdgware.SR5Finchley.SR2Finchley.BUILD-SNAPSHOT
spring-cloud-aws1.2.3.RELEASE2.0.1.RELEASE2.0.1.BUILD-SNAPSHOT
spring-cloud-bus1.3.3.RELEASE2.0.0.RELEASE2.0.1.BUILD-SNAPSHOT
spring-cloud-cli1.4.1.RELEASE2.0.0.RELEASE2.0.1.BUILD-SNAPSHOT
spring-cloud-commons1.3.5.RELEASE2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-contract1.2.6.RELEASE2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-config1.4.5.RELEASE2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-netflix1.4.6.RELEASE2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-security1.2.3.RELEASE2.0.1.RELEASE2.0.1.BUILD-SNAPSHOT
spring-cloud-cloudfoundry1.1.2.RELEASE2.0.1.RELEASE2.0.1.BUILD-SNAPSHOT
spring-cloud-consul1.3.5.RELEASE2.0.1.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-sleuth1.3.5.RELEASE2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-streamDitmars.SR4Elmhurst.SR1Elmhurst.BUILD-SNAPSHOT
spring-cloud-zookeeper1.2.2.RELEASE2.0.0.RELEASE2.0.1.BUILD-SNAPSHOT
spring-boot1.5.16.RELEASE2.0.6.RELEASE2.0.7.BUILD-SNAPSHOT
spring-cloud-task1.2.3.RELEASE2.0.0.RELEASE2.0.1.BUILD-SNAPSHOT
spring-cloud-vault1.1.2.RELEASE2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-gateway1.0.2.RELEASE2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-openfeign2.0.2.RELEASE2.0.2.BUILD-SNAPSHOT
spring-cloud-function1.0.1.RELEASE1.0.0.RELEASE1.0.1.BUILD-SNAPSHOT

注意:

SpringCloud 版本为 Edgware 及以下,eureka包改为:

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

SpringCloud 版本为 Edgware 以上,eureka包改为netflix:

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

SpringCloudEureka

入门案例(一) Server与Client

入门案例(二)Server、Porvider与Consumer

项目整体结构:

在这里插入图片描述

eureka-server入门
一、导入jar
<?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>

    <artifactId>lemon-soa</artifactId>
    <packaging>jar</packaging>

    <name>spring-cloud-eureka-server</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <spring-cloud.version>Dalston.SR4</spring-cloud.version>
    </properties>

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

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

二、建立启动类
package com.lemon.eureka.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author sjp
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

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

}
三、配置yml
server:
    port: 9001

eureka:
    instance:
        hostname: eureka-service
    client:
        # 不注册自己
        register-with-eureka: false
        # 获取服务
        fetch-registry: false
        # 注册中心地址
        service-url:
            defaultZone: http://localhost:${server.port}/eureka/

四、访问

http://localhost:9001/
在这里插入图片描述

eureka-api 入门

Tips:此部分属于provider和consumer公用部分,所以单独作为一个模块,打包成jar供provider和consumer使用

模块结构

在这里插入图片描述

一、导入jar
<?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>

    <artifactId>eureka-api</artifactId>

</project>

二、建立相关类
package com.lemon.soa.api;

public interface VideoService {
   /**
    * 获取视频信息
    * @param videoId 视频id
    * @return 视频信息
    */
   double getVideo(long videoId);
}
eureka-provider入门

Tips: Eureka本身只区分server和client(client有provider和consumer),通过不同的配置来告知client,本身是provider还是consumer.

模块结构

在这里插入图片描述

一、导入jar
<?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>

    <artifactId>eureka-provider</artifactId>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR4</spring-cloud.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</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>com.lemon</groupId>
            <artifactId>eureka-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

    </dependencies>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

二、建立相关类

启动类:

package com.lemon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {

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

}

服务接口实现:

package com.lemon.api.impl;

import org.springframework.stereotype.Service;

import com.lemon.soa.api.VideoService;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@Service
public class VideoServiceImpl implements VideoService {
   @Override
   public double getVideo(long videoId) {
      return Math.random();
   }
}

暴露服务:

package com.lemon.controller;

import com.lemon.soa.api.VideoService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class VideoController {

   @Resource
   private VideoService videoService;

   @RequestMapping(value = "/{videoId}", method = RequestMethod.GET)
   public Double getVideo(@PathVariable long videoId) {
      return videoService.getVideo(videoId);
   }
}
三、配置yml
server:
    port: 9002

spring:
    application:
        name: eureka-provider

eureka:
    instance:
        #使用ip进行注册
        prefer-ip-address: true
    client:
        serviceUrl:
            defaultZone: http://localhost:9001/eureka/
四、访问

http://localhost:9001/

在这里插入图片描述

eureka-consumer入门
模块结构

在这里插入图片描述

一、导入jar
<?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>

    <artifactId>eureka-consumer</artifactId>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
    </parent>

    <properties>
        <spring-cloud.version>Edgware.SR3</spring-cloud.version>
    </properties>

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

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

</project>

二、建立相关类

启动类:

package com.lemon.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaConsumerApplication {

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

	/**
	 * 启用负载均衡,默认算法是轮询
	 */
	@LoadBalanced
	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
}

调用服务:

package com.lemon.consumer.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@RestController
public class ConsumerController {

   @Resource
   private RestTemplate restTemplate;

   @RequestMapping("/")
   public Double index() {
        return restTemplate.getForObject("http://eureka-provider/1", Double.class);
   }
}
三、配置yml
server:
    port: 9003

spring:
    application:
        name: eureka-consumer
eureka:
    instance:
        # 使用IP注册
        prefer-ip-address: true
    #注册地址
    client:
        service-url:
            defaultZone: http://localhost:9001/eureka/
四、访问

http://localhost:9001/

在这里插入图片描述

熟悉掌握

eureka-server配置详解
参数名默认值备注
enable-self-preservationtrue自我保护模式,当出现出现网络分区、eureka在短时间内丢失过多客户端时,会进入自我保护模式,即一个服务长时间没有发送心跳,eureka 也不会将其删除,默认为true
eviction-interval-timer-in-ms60000eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
a-s-g-cache-expiry-timeout-ms6000缓存ASG信息的到期时间,单位为毫秒,默认为10 * 60 * 1000
a-s-g-query-timeout-ms300查询AWS上ASG(自动缩放组)信息的超时值,单位为毫秒,默认为300
a-s-g-update-interval-ms5 * 60 * 1000从AWS上更新ASG信息的时间间隔,单位为毫秒
a-w-s-access-id获取aws访问的id,主要用于弹性ip绑定,此配置是用于aws上的
a-w-s-secret-key获取aws私有秘钥,主要用于弹性ip绑定,此配置是用于aws上的
batch-replicationfalse表示集群节点之间的复制是否为了网络效率而进行批处理
binding-strategy获取配置绑定EIP或Route53的策略
delta-retention-timer-interval-in-ms30 * 1000清理任务程序被唤醒的时间间隔,清理过期的增量信息,单位为毫秒
disable-deltafalse增量信息是否可以提供给客户端看,默认为false
disable-delta-for-remote-regionsfalse增量信息是否可以提供给客户端或一些远程地区
disable-transparent-fallback-to-other-regionfalse如果在远程区域本地没有实例运行,对于应用程序回退的旧行为是否被禁用
e-i-p-bind-rebind-retries3获取服务器尝试绑定到候选的EIP的次数
e-i-p-binding-retry-interval-ms-when-unbound1 * 60 * 1000服务器检查ip绑定的时间间隔,单位为毫秒
e-i-p-binding-retry-interval-ms5 * 60 * 1000与上面的是同一作用,仅仅是稳定状态检查
enable-replicated-request-compressionfalse复制的数据在发送请求时是否被压缩
g-zip-content-from-remote-regiontrueeureka服务器中获取的内容是否在远程地区被压缩,默认为true
json-codec-name如果没有设置默认的编解码器将使用全JSON编解码器,获取的是编码器的类名称
list-auto-scaling-groups-role-nameListAutoScalingGroups用来描述从AWS第三账户的自动缩放组中的角色名称
log-identity-headerstrueEureka服务器是否应该登录clientAuthHeaders
max-elements-in-peer-replication-pool10000复制池备份复制事件的最大数量
max-elements-in-status-replication-pool:10000可允许的状态复制池备份复制事件的最大数量
max-idle-thread-age-in-minutes-for-peer-replication10状态复制线程可以保持存活的空闲时间
min-threads-for-status-replication1被用于状态复制的线程的最小数目
max-idle-thread-in-minutes-age-for-status-replication15复制线程可以保持存活的空闲时间,默认为15分钟
max-threads-for-peer-replication20获取将被用于复制线程的最大数目
max-time-for-replication30000尝试在丢弃复制事件之前进行复制的时间,默认为30000毫秒
min-threads-for-peer-replication5获取将被用于复制线程的最小数目
number-of-replication-retries5获取集群里服务器尝试复制数据的次数
peer-eureka-nodes-update-interval-ms10 * 60 * 1000集群里eureka节点的变化信息更新的时间间隔,单位为毫秒
peer-eureka-status-refresh-time-interval-ms30 * 1000服务器节点的状态信息被更新的时间间隔,单位为毫秒
peer-node-connect-timeout-ms200连接对等节点服务器复制的超时的时间,单位为毫秒
peer-node-read-timeout-ms200读取对等节点服务器复制的超时的时间,单位为毫秒
peer-node-total-connections1000获取对等节点上http连接的总数
peer-node-connection-idle-timeout-seconds30http连接被清理之后服务器的空闲时间,默认为30秒
peer-node-total-connections-per-host500获取特定的对等节点上http连接的总数
prime-aws-replica-connectionstrue对集群中服务器节点的连接是否应该准备
rate-limiter-enabled限流是否应启用或禁用,默认为false
rate-limiter-burst-size速率限制的burst size ,默认为10,这里用的是令牌桶算法
rate-limiter-full-fetch-average-rate100速率限制器用的是令牌桶算法,此配置指定平均执行请求速率,默认为100
rate-limiter-privileged-clients认证的客户端列表,这里是除了标准的eureka Java客户端。
rate-limiter-registry-fetch-average-rate500速率限制器用的是令牌桶算法,此配置指定平均执行注册请求速率,默认为500
rate-limiter-throttle-standard-clientsfalse是否对标准客户端进行限流,默认false
registry-sync-retries5当eureka服务器启动时尝试去获取集群里其他服务器上的注册信息的次数,默认为5
registry-sync-retry-wait-ms30 * 1000当eureka服务器启动时获取其他服务器的注册信息失败时,会再次尝试获取,期间需要等待的时间,默认为30 * 1000毫秒
remote-region-app-whitelist必须通过远程区域中检索的应用程序的列表
remote-region-connect-timeout-ms1000连接到对等远程地eureka节点的超时时间,默认为1000毫秒
remote-region-connection-idle-timeout-seconds30http连接被清理之后远程地区服务器的空闲时间,默认为30秒
remote-region-fetch-thread-pool-size20用于执行远程区域注册表请求的线程池的大小,默认为20
remote-region-read-timeout-ms1000获取从远程地区eureka节点读取信息的超时时间,默认为1000毫秒
remote-region-registry-fetch-interval30从远程区域取出该注册表的信息的时间间隔,默认为30秒
remote-region-total-connections1000获取远程地区对等节点上http连接的总数,默认为1000
remote-region-total-connections-per-host500获取远程地区特定的对等节点上http连接的总数,默认为500
remote-region-trust-store用来合格请求远程区域注册表的信任存储文件,默认为空
remote-region-trust-store-password获取偏远地区信任存储文件的密码,默认为“changeit”
remote-region-urls远程地区的URL列表
remote-region-urls-with-name针对远程地区发现的网址域名的map
renewal-percent-threshold0.85阈值因子,默认是0.85,如果阈值比最小值大,则自我保护模式开启
renewal-threshold-update-interval-ms15 * 60 * 1000阈值更新的时间间隔,单位为毫秒
response-cache-auto-expiration-in-seconds180当注册表信息被改变时,则其被保存在缓存中不失效的时间,默认为180秒
response-cache-update-interval-ms30 * 1000客户端的有效负载缓存应该更新的时间间隔,默认为30 * 1000毫秒
retention-time-in-m-s-in-delta-queue3 * 60 * 1000客户端保持增量信息缓存的时间,从而保证不会丢失这些信息,单位为毫秒
route53-bind-rebind-retries3服务器尝试绑定到候选Route53域的次数
route53-binding-retry-interval-ms5 * 60 * 1000服务器应该检查是否和Route53域绑定的时间间隔,默认为5 * 60 * 1000毫秒
route53-domain-t-t-l301用于建立route53域的ttl,默认为301
sync-when-timestamp-differstrue当时间变化实例是否跟着同步,默认为true
use-read-only-response-cachetrue目前采用的是二级缓存策略,一个是读写高速缓存过期策略,另一个没有过期只有只读缓存,默认为true,表示只读缓存
wait-time-in-ms-when-sync-empty1000 * 60 * 5在Eureka服务器获取不到集群里对等服务器上的实例时,需要等待的时间,单位为毫秒,默认为1000 * 60 * 5
xml-codec-name如果没有设置默认的编解码器将使用xml编解码器,获取的是编码器的类名称

SpringCloudFegin

官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.0.2.RELEASE/single/spring-cloud-openfeign.html

一、导入jar

Springboot 2.0.0 以下

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

Springboot 2.0.0 及以上

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
二、建立相关类

启动类(加上注解):

/**
  * 如果为了把eureka共有接口抽成单独模块,需注明扫描包,才可以加载jar包中的@FeignClient
  * @EnableFeignClients(basePackages = { "com.lemon.soa.api" })
  */
@EnableFeignClients

修改类:

package com.lemon.soa.api;

// 其中eureka-provider是提供服务者的应用名,即eureka-provider的应用名
@FeignClient(name = "eureka-provider")
public interface VideoService {
   /**
    * 获取视频信息
    * @param videoId 视频id
    * @return 视频信息
    */
   @GetMapping(value = "/{videoId}")
   double getVideo(long videoId);
}

调用服务:

package com.lemon.consumer.controller;

import com.lemon.soa.api.dto.CategoryDTO;
import com.lemon.soa.api.provider.CategoryProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@RestController
public class ConsumerController {
 
	/**
	 * feign 方式
	 */
	@Resource
	private CategoryProvider categoryProvider;

	@GetMapping(value = "/category")
	public List<CategoryDTO> getCategoryTree() {
		return categoryProvider.getCategoryTree();
	}

}

三、配置yml
server:
    port: 9003

spring:
    application:
        name: eureka-consumer
eureka:
    instance:
        # 使用IP注册
        prefer-ip-address: true
    #注册地址
    client:
        service-url:
            defaultZone: http://localhost:9001/eureka/
四、访问

http://localhost:9001/

在这里插入图片描述
坑:

问题一:

有些公共的组件抽出来其他模块的maven依赖,此时要在使用的项目中加载此jar包的spring component以及feign组件,仅仅依靠@ComponentScan是不够的,还需要在@EnableFeignClients(basePackages = {“com.xixicat”})中标注basekPackages。

问题二:

使用@FeignClient注解,要求name不重复,否则Bean会被覆盖,或者无法启动。这是Feign的一个缺点吧。

推荐修复方案:

spring:

    # 允许重复名称的bean定义,为了解决Fegin重复命名无法启动的问题
    main:
        allow-bean-definition-overriding: true

其他修复方案(手动初始化Feign代理的类):

package com.lemon.consumer.controller;

import com.lemon.soa.api.dto.CategoryDTO;
import com.lemon.soa.api.dto.VideoDTO;
import com.lemon.soa.api.provider.CategoryProvider;
import com.lemon.soa.api.provider.VideoProvider;
import feign.Client;
import feign.Contract;
import feign.Feign;
import feign.Logger;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.slf4j.Slf4jLogger;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * FeginMutiNameController Fegin的一个缺陷,feginName不可以重复定义(除set allow-bean-definition-overriding: true的第二种方案)
 * @author sjp
 * @date 2019/12/15
 */
@RestController
@Import(FeignClientsConfiguration.class)
public class FeginMutiNameController {

	private VideoProvider		videoProvider;
	private CategoryProvider	categoryProvider;

	public FeginMutiNameController(Decoder decoder, Encoder encoder, Client client, Contract contract) {
		this.videoProvider = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
				// 默认是Logger.NoOpLogger
				.logger(new Slf4jLogger(VideoProvider.class))
				// 默认是Logger.Level.NONE
				.logLevel(Logger.Level.FULL).target(VideoProvider.class, "http://provider");

		this.categoryProvider = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
				// 默认是Logger.NoOpLogger
				.logger(new Slf4jLogger(CategoryProvider.class))
				// 默认是Logger.Level.NONE
				.logLevel(Logger.Level.FULL).target(CategoryProvider.class, "http://provider");
	}

	@GetMapping(value = "/test1")
	public List<CategoryDTO> getCategoryTree() {
		return categoryProvider.getCategoryTree();
	}

	@GetMapping(value = "/test2/{id}")
	public VideoDTO index(@PathVariable(value = "id") Long id) {
		return videoProvider.getVideo(id);
	}

}

SpringCloud使用Config作为配置中心

一、介绍

​ 服务端:配置中心

​ 客户端:接受配置的应用

二、配置

1、Server端配置
A、pom
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-parent</artifactId>
    <version>1.5.13.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
  </dependencies>

  <!-- 添加spring-boot的maven插件 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
B、yml
server:
    port: 9000
spring:
    application:
        name: lemon-config-server
    cloud:
        config:
            server:
                git:
                	# SpringCloud Config 的配置是放在git上的
                    uri: https://github.com/ATSJP/lemon-config
                    # 指定搜索根路径下的所有目录,若有多个路径使用逗号隔开
                    search-paths: /**  
C、Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

/**
 * @author sjp
 */
@EnableConfigServer
@SpringBootApplication
public class LemonConfigApplication {

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

}

全部配置好后,启动应用,访问 http://localhost:9000/admin/dev (http://localhost:9000/admin-dev.json,http://localhost:9000/admin-dev.properties)

在这里插入图片描述

注:配置文件的访问规则如下:

/{name}-{profiles}.yml
/{label}/{name}-{profiles}.yml

name : 文件名,一般以服务名来命名
profiles : 一般作为环境标识
lable : 分支(branch),指定访问某分支下的配置文件

例如:http://localhost:9000/dv_lemon_2019_07/provider-dev.yml

有一点值得注意的是,如果有两个前缀名相同文件,例如一个order.yml,一个order-dev.yml。那么在访问相同前缀的文件时,config-server会对这两个文件进行一个合并。例如order.yml有一段配置是order-dev.yml没有的,理应访问order-dev.yml的时候是没有那段配置的,但访问的结果却是它俩合并之后的内容,即order-dev.yml会拥有order.yml里所配置的内容。

2、Client端配置
A、pom
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-parent</artifactId>
    <version>1.5.13.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 实现Config的客户端配置 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <!-- 实现通过端点refresh手动刷新 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  </dependencies>
  
  <!-- 添加spring-boot的maven插件 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
B、yml
  1. bootstrap.yml
# 对应着config server所获取配置文件的{application}和URL
spring:
    application:
        name: admin
    cloud:
        config:
            uri: http://localhost:9000/
            # 对应着文件后面的后缀{profile}
            profile: dev
            # 分支
            label: master
  1. application.yml
version-config: ${version}
C、Application
@SpringBootApplication
public class LemonAdminApplication {

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

}
D、Controller
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller
@RestController
public class LoginController {

    @Value("${version-config}")
    private String version;

    @GetMapping("/test")
    public String getVersion() {
        return this.version;
    }
    
}

三、踩坑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值