从0到1的Springcloud Alibaba项目,一篇入门!!!

news2024/9/28 23:27:18

1、新建项目

我们用maven管理项目

第一步:选择maven

第二步:项目命名,项目路径

第三步:进入项目,把src文件夹删掉(不删也没事,主要是用不到这个文件夹)

2、引入项目依赖

在父项目pom文件加入下面依赖。

注:springboot项目版本与cloud版本有一定的对应关系,在官网可以看到,下面是对应的版本关系,选择合适的即可。

本项目所用依赖版本:

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

    <groupId>org.example</groupId>
    <artifactId>project_springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <!--springboot版本-->
        <spring.boot.version>2.3.8.RELEASE</spring.boot.version>
        <!--springcloud版本-->
        <spring.cloud.version>Hoxton.SR10</spring.cloud.version>
        <!--springcloudalibaba版本-->
        <spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
    </properties>

    <!-- 管理依赖的版本 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>

注意:

  1. 父工程dependencyManagement中管理的依赖在你们仓库中可能没有,所以要注释dependencyManagement先下载对应版本的依赖
  2. dependencyManagement只是声明依赖,并不实现引入,因此子项目需要显示声明需要用的依赖

3、Nacos服务注册和发现

3.1、Nacos下载与启动

模拟生产环境,采用Linux部署

第一步:官网下载nacos(Nacos | Nacos),下载不了的可以关注公众号【JavaCoding】回复nacos获取

第二步:进入bin文件,修改startup.sh配置文件,下载的默认启动配置需要的内存太大,改小一点

第三步:命令启动sh startup.sh -m standalone,注:这里standalone参数代表着单机模式运行,非集群模式

控制台输出这样的内容代表启动成功,我们打开start.out日志查看内容:

3.2、服务注册

第一步:新建一个服务service1

要在父级目录下创建service1项目,具体步骤与上述创建父项目类似,过程省略,创建后的项目结构如下:

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">
    <parent>
        <artifactId>project_springcloud</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service1</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <!--nacos服务注册-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>nacos-client</artifactId>
                    <groupId>com.alibaba.nacos</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>nacos-client</artifactId>
                    <groupId>com.alibaba.nacos</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--单独指定nacos client版本(自带的版本会在控制台一直输出日志)-->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.4.2</version>
        </dependency>

    </dependencies>

</project>

第二步:登录我们启动的nacos地址,新建一个命名空间

第三步:点击配置列表右侧加号,新建一个配置

第四步:yml中配置(注意这里项目中配置文件名一定要是bootstrap)

spring:
  application:
    name: service1
  cloud:
    nacos:
      discovery:
        # 你的服务器ip
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
      config:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
        prefix: service1
        group: DEFAULT_GROUP
        file-extension: yaml

最后启动项目:

我们可以看到,项目端口是用的我们nacos里配置里写好的端口

点开nacos服务列表:

我们可以看到我们启动的服务已经注册进来了,这里的服务名就是我们项目里spring.application.name配置的名

最后接口测试:

注意:

我们这里的启动类并没有加@EnableDiscoveryClient注解,是因为从Spring Cloud Edgware开始,这个注解可以省略。但是maven依赖中必须要有spring-cloud-starter-alibaba-nacos-discovery服务注册的依赖。

但是值得注意的是,如果使用了Eureka作为注册中心,那么需要使用@EnableEurekaClient注解来启动Eureka客户端。因此,是否需要省略@EnableDiscoveryClient注解取决于你的具体需求和使用的服务注册中心类型。

4、Gateway网关服务

4.1、项目引入

第一步:新建Gateway项目,过程省略,项目结构如下

第二步:引入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">
    <parent>
        <artifactId>project_springcloud</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--nacos服务注册-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>nacos-client</artifactId>
                    <groupId>com.alibaba.nacos</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>nacos-client</artifactId>
                    <groupId>com.alibaba.nacos</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--单独指定nacos client版本(自带的版本会在控制台一直输出日志)-->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.4.2</version>
        </dependency>

    </dependencies>

</project>

第三步:nacos新增配置文件,与service1一样,端口我们设置为8002

第四步:配置文件

spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
      config:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
        prefix: gateway
        group: DEFAULT_GROUP
        file-extension: yaml

第五步:启动项目

在nacos里可以看到我们的Gateway服务已经注册进来了

4.2、路由配置

上面步骤我们只是把Gateway服务启动,并没有体现出Gateway的作用,我们想要看到的是通过访问不通的接口,Gateway可以帮我自动找到到相应的服务。

简单介绍Gateway配置项:

路由(Route):由ID、目标URI、断言集合和过滤器集合组成。如果聚合断言结果为真,则转发到该路由。

(1)id:路由标识,要求唯一,名称任意(默认值 uuid,一般不用,需要自定义)

(2)uri:请求最终被转发到的目标地址

(3)order: 路由优先级,数字越小,优先级越高

(4)predicates:断言数组,即判断条件,如果返回值是boolean,则转发请求到 uri 属性指定的服务中

(5)filters:过滤器数组,在请求传递过程中,对请求做一些修改

断言(Predicate):参照 Java8 的新特性Predicate,允许开发人员匹配 HTTP 请求中的任何内容,比如请求头或请求参数,最后根据匹配结果返回一个布尔值。

Predicate 来自于 Java8 的接口。Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。

Predicate 可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。Spring Cloud Gateway 内置了许多 Predict,这些 Predict 的源码在 org.springframework.cloud.gateway.handler.predicate 包中,有兴趣可以阅读一下。

过滤器(Filter):可以在返回请求之前或之后修改请求和响应的内容。

Gateway 过滤器的生命周期:

PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。

POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

Gateway 过滤器从作用范围可分为两种:

GatewayFilter:应用到单个路由或者一个分组的路由上(需要在配置文件中配置)

GlobalFilter:应用到所有的路由上(无需配置,全局生效)

有两种方式可以实现Gateway路由配置:

准备工作:我们先按照service1服务创建一个service2服务,端口用8003,创建后的项目架构:

service1和service2接口方法如下:

第一种:yml配置

在Gateway项目的yml中加入以下配置:

spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
      config:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
        prefix: gateway
        group: DEFAULT_GROUP
        file-extension: yaml
    # gateway 配置
    gateway:
      # 路由数组:指当请求满足什么样的断言时,转发到哪个服务上
      routes:
          # 路由唯一标识
        - id: gateway-service1
          # 要转发到哪个服务,我们这里不直接写ip:端口的形式,因为一旦服务的域名或IP地址发生修改,路由配置中的 uri 就必须修改
          # 使用了lb形式,从注册中心负载均衡的获取uri
          uri: lb://service1
          # 设置断言
          predicates:
              # 满足/service1的请求路径会路由到localhost:8001服务
            - Path=/service1/**
          # 过滤器
          filters:
            # 去除原始请求路径中的前1级路径,也就是/service1
            - StripPrefix=1

          # 路由唯一标识
        - id: gateway-service2
          # 要转发到哪个服务
          uri: lb://service2
          # 设置断言
          predicates:
            # 满足/service1的请求路径会路由到localhost:8001服务
            - Path=/service2/**
          # 过滤器
          filters:
            # 去除原始请求路径中的前1级路径,也就是/service1
            - StripPrefix=1

启动项目:

通过网关访问service1服务的接口:

通过网关访问service2服务的接口:

结论:虽然两个服务接口地址一样,但通过网关配置,我们可以根据不同的请求路径前缀来访问不通的服务

第二种:代码配置

通过代码我们可以更加灵活的对Gateway进行配置,面对的场景也更加复杂。

第一步:先把yml中Gateway配置注释

第二步:添加自定义配置类

package com.javacoding.config;

import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.*;

@Component
public class MyRouteDefinitionRepository implements RouteDefinitionRepository {
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> routeDefinitions = new ArrayList<>();
        // service1的route配置
        RouteDefinition service1 = setService1();
        // service2的route配置
        RouteDefinition service2 = setService2();
        routeDefinitions.add(service1);
        routeDefinitions.add(service2);
        return Flux.fromIterable(routeDefinitions);
    }

    private RouteDefinition setService2() {
        RouteDefinition definition = new RouteDefinition();
        // id
        definition.setId("service2");
        URI uri = UriComponentsBuilder.fromUriString("lb://service2").build().toUri();
        // uri
        definition.setUri(uri);

        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName("Path");

        Map<String, String> predicateParams = new HashMap<>(8);
        predicateParams.put("pattern", "/service2/**");
        predicate.setArgs(predicateParams);

        //定义Filter
        FilterDefinition filter = new FilterDefinition();
        filter.setName("StripPrefix");
        Map<String, String> filterParams = new HashMap<>(8);
        //该_genkey_前缀是固定的,见org.springframework.cloud.gateway.support.NameUtils类
        filterParams.put("_genkey_0", "1");
        filter.setArgs(filterParams);

        definition.setFilters(Collections.singletonList(filter));
        definition.setPredicates(Collections.singletonList(predicate));
        return definition;
    }

    private RouteDefinition setService1() {
        RouteDefinition definition = new RouteDefinition();
        // id
        definition.setId("service1");
        URI uri = UriComponentsBuilder.fromUriString("lb://service1").build().toUri();
        // uri
        definition.setUri(uri);

        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName("Path");

        Map<String, String> predicateParams = new HashMap<>(8);
        predicateParams.put("pattern", "/service1/**");
        predicate.setArgs(predicateParams);

        //定义Filter
        FilterDefinition filter = new FilterDefinition();
        filter.setName("StripPrefix");
        Map<String, String> filterParams = new HashMap<>(8);
        //该_genkey_前缀是固定的,见org.springframework.cloud.gateway.support.NameUtils类
        filterParams.put("_genkey_0", "1");
        filter.setArgs(filterParams);

        definition.setFilters(Collections.singletonList(filter));
        definition.setPredicates(Collections.singletonList(predicate));
        return definition;
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return null;
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return null;
    }
}

第三步:启动项目测试

总结:这些只是基础的配置,实际生产中还会有自定义全局过滤器等。

5、Feign服务调用

5.1、服务调用

当我们在service1调用service2中的接口时,传统的项目我们直接用maven引入service2项目就可以直接调用。但在微服务中,各个项目都是独立存在的,我们如果用http去调用每次都非常繁琐,而且不方便拓展。因此Feign就是解决这个问题。

第一步:创建Feign项目,过程省略,项目结构如下

第二步: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">
    <parent>
        <artifactId>project_springcloud</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>feign</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

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

第三步:yml配置

spring:
  application:
    name: feign
  cloud:
    nacos:
      discovery:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
      config:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
        prefix: feign
        group: DEFAULT_GROUP
        file-extension: yaml

第四步:写feign客户端接口

package com.javacoding.service;

import com.javacoding.service.impl.Service2ClientBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = "service2", fallback = Service2ClientBack.class)
public interface Service2Client {

    @RequestMapping("/test/msg")
    public String test(@RequestParam("msg") String msg);

}

说明:

1. @FeignClient注解标识当前接口是feign调用接口,value代表哪个服务调用接口,这里我们想调用service2服务,所以写service2(为什么写service2,因为service2服务里的配置文件spring.application.name,与他保持一致);fallback是如果服务调用失败,我该怎么处理,这个类就是处理这个问题的。

2. 接口请求路径,请求名和方法与service2要调用的接口保持一致。

package com.javacoding.service.impl;

import com.javacoding.service.Service2Client;
import org.springframework.stereotype.Component;

/**
 * 调用失败返回
 */
@Component
public class Service2ClientBack implements Service2Client {
    @Override
    public String test(String msg) {
        return "service2服务调用失败!!!";
    }
}

第五步:在service1通过feign实现service2接口请求响应

1、在pom中加入feign依赖

<!--feign类引用-->
<dependency>
    <groupId>org.example</groupId>
    <artifactId>feign</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<!--feign服务依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、启动类添加@EnableFeignClients注解

package com.javacoding;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

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

3、controller添加调用的方法

package com.javacoding.controller;

import com.javacoding.service.Service2Client;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/test")
public class TestController {
    
    @Resource
    private Service2Client service2Client;

    @GetMapping("/msg")
    public String test(@RequestParam("msg") String msg) {
        return "service1:" + msg;
    }

    /**
     * 通过feign调用service2的接口
     * 
     * @param msg
     * @return
     */
    @GetMapping("/feign/msg")
    public String test2(@RequestParam("msg") String msg) {
        String result = service2Client.test(msg);
        return "通过feign调用请求返回:" + result;
    }

}

4、测试

总结:我们并没有在service1中引入service2的服务,也实现了调用service2服务中的接口。之后我们想要在微服务中引入其他服务只需写一个某某服务的接口(xxxClient)利用@FeignClient注解指明哪个服务,通过这个接口就可以去调用我们的目标服务的接口。

5.2、服务降级

前面我在@FeignClient注解里加了fallback参数。Fallback是通过Hystrix实现的, 所以需要开启Hystrix,spring boot application.properties文件配置feign.hystrix.enabled=true,这样就开启了Fallback。

service1的nacos中的yml配置:

server:
    port: 8001

feign:
  hystrix:
      enabled: true

service2中服务抛出个异常,模拟服务不可用:

package com.javacoding.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/msg")
    public String test(@RequestParam("msg") String msg) {
        throw new RuntimeException();
//        return "service2:" + msg;
    }

}

测试:

5.3、负载均衡

如果我们service2服务是非常重要的,我们通过会部署好几个防止其中一个崩溃导致服务不可用,那么service1在通过feign调用的时候到底调用了哪一个service2呢?如何把请求进行分配呢?

第一步:先把service2的nacos配置的端口注释掉,改为写在项目bootstrap.yml里面。经过测试发现,如果不写在项目bootstrap.yml里面,后续我们启动两个service2服务的时候会一直用nacos配置里的端口。

spring:
  application:
    name: service2
  cloud:
    nacos:
      discovery:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
      config:
        server-addr: 114.115.xxx.xx:8848
        namespace: 900c8c5e-b442-4b61-abf4-90b640e643ea
        prefix: service2
        group: DEFAULT_GROUP
        file-extension: yaml
server:
  port: 8003

第二步:改造一下service2中的方法,返回信息中加入端口信息,方便区分请求的是哪个服务

package com.javacoding.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/msg")
    public String test(@RequestParam("msg") String msg, HttpServletRequest request) {
//        throw new RuntimeException();
        int serverPort = request.getServerPort();
        return "service2:" + msg + ",端口:" + serverPort;
    }

}

第三步:启动网关、service1、service2服务,然后复制service2更改端口启动,这样service2服务就启动了两个实例。

所有服务启动后nacos里的实例信息如下:

第四步:测试接口

总结:可以看到我们的请求在8003和8004端口来回切换,这就是默认的轮训策略。

拓展:除了默认的轮训还有哪些策略?

通常我们都是自定义的方式来配置我们的负载均衡策略,这样我们会有更多的操作空间。

在service1中我们自定义配置:

package com.javacoding.config;

import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class FeignBalanceConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getResTemplate() {
        return new RestTemplate();
    }

//    @Bean
//    public RoundRobinRule getRule() {
//        // 轮训
//        return new RoundRobinRule();
//    }

    @Bean
    public RandomRule getRule() {
        //随机策略
        return new RandomRule();
    }
}

测试随机策略:

还有其他一些策略,不在一一演示了,配置如下:

@Bean
public AvailabilityFilteringRule getRule() {
    //首先会过滤掉故障机或者并发链接数超过阈值的服务器.剩余的机器轮询配置
     return new AvailabilityFilteringRule();
}


@Bean
public WeightedResponseTimeRule getRule() {
    //服务器影响时间越快,则权重越高
     return new WeightedResponseTimeRule();
}


@Bean
public BestAvailableRule getRule() {
    //最大可用策略,即先过滤出故障服务器后,选择一个当前并发请求数最小的
    return new BestAvailableRule();
}

ok,以上内容如果都学会并了解那代表你已经可以用springcloud微服务应对90%开发需求了。当然还有Hystrix、Ribbon组件,虽然没讲如何用,但这两个组件Feign都已经很好了集成了,如果你面对的是非常复杂的开发场景,那也可以单独去配置这两个组件(原理都是一样的)。

希望这篇微服务项目可以带你很好的入门~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1181535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

matlab 读写ENVI标准数据

本博客主要讲解如何读、生成ENVI标准格式的数据。主要分为四部分&#xff1a;读取ENVI头文件、读取ENVI数据、写入ENVI头文件、生成ENVI标准数据&#xff0c;最后附加讲解了本人写的生成hdr文本文件代码。此外&#xff0c;文中还具体介绍写代码的一些思路。 一、读取ENVI头文件…

【数据结构】单链表之--无头单向非循环链表

前言&#xff1a;前面我们学习了动态顺序表并且模拟了它的实现&#xff0c;今天我们来进一步学习&#xff0c;来学习单链表&#xff01;一起加油各位&#xff0c;后面的路只会越来越难走需要我们一步一个脚印&#xff01; &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x…

kafka可视化工具

Offset Explorer kafka可视化工具

Spring Boot 统一处理功能

目录 1.用户登陆权限验证 1.1 每个方法验证 1.2 Spring AOP 用户统一登陆验证 1.3 拦截器 1.3.1 自定义拦截器 1.3.2 将自定义拦截器配置到系统设置中&#xff0c;并且设置拦截规则 1.3.3 排除所有的静态资源 1.4 登录拦截器&#xff08;练习&#xff09; 1.5 拦截器原…

二叉树—相关计算题

目录 一、概念题 二、计算题 1、节点数 2、深度 3、遍历序列 一、概念题 1、在用树表示的目录结构中&#xff0c;从根目录到任何数据文件&#xff0c;有&#xff08; &#xff09;通道 答案&#xff1a;唯一一条&#xff0c;树的特点是不相交&#xff0c;所以不可能有多…

CAN总线数据采集工具PCAN的使用教程

系列文章目录 文章目录 系列文章目录pcan使用PCAN-Explorer 5安装PCAN-USB Pro安装如下PEAK-System_Driver-Setup安转如下PCAN-View操作步骤 通讯测试检查安装成果trace 文件下载 pcan使用 PCAN-Explorer 5安装 默认路径——all user——yes——next——finish PCAN-USB Pro…

洛谷P1024 [NOIP2001 提高组] 一元三次方程求解(优雅的暴力+二分,干净利落)

P1024 [NOIP2001 提高组] 一元三次方程求解 前言题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 题目分析注意事项 代码后话额外测试用例样例输入 #2样例输出 #2 王婆卖瓜 题目来源 前言 没有前言&#xff0c;可能因为作者忘了编辑 题目 题目描述 有形如&…

异常断电文件损坏docker服务异常处理

问题场景 我们在某地部署信控平台&#xff0c;当初是在产品研发早期&#xff0c;采取的还是Windows服务器部署虚拟机的方式使用virtualbox导入centos7虚拟机&#xff0c;虚拟机里运行docker服务&#xff0c;使用docker-compose统一管理客户今天上午反馈&#xff0c;昨天断电了…

Pygame游戏实战四:打砖块

介绍模块 本游戏使用的是由Pycharm中的pygame模块来实现的&#xff0c;也可以在python中运行。通过Pygame制作一个打砖块&#xff0c;通过击打砖块来得到更多的分数&#xff0c;看看这个是你小时候玩的游戏吗&#xff1f; 最小开发框架 详情请看此文章&#xff1a;Pygame游戏…

界面组件Telerik UI for WinForms中文教程 - 如何自定义应用程序文件窗口?

Telerik UI for WinForms包含了一个高度可定制的组件&#xff0c;它取代了.NET中默认的OpenFileDialog。在下一个更新版本中&#xff0c;会发布一个向对话框浏览器提那家自定义位置的请求功能&#xff0c;本文演示了这个和另一个自定义功能&#xff0c;它可以帮助用户在浏览文件…

【题解】2023 DTS算法竞赛集训 第1次

比赛地址&#xff1a;https://www.luogu.com.cn/contest/143650 P1319 压缩技术 https://www.luogu.com.cn/problem/P1319 简单的签到模拟题 #include <iostream>//c标准库 using namespace std; int main(){int a,n,t0,i0,b,s0;//t判断有没有回车&#xff0c;i判断输…

分支限界法求解迷宫问题

问题描述 从入口出发&#xff0c;按某一方向向前探索&#xff0c;若能走通(未走过的&#xff09;&#xff0c;即某处可以到达&#xff0c;则到达新点&#xff0c;否则试探下一方向&#xff1b;若该点所有的方向均没有通路&#xff0c;则沿原路返回到前一点&#xff0c;换下一个…

一台抵得上多种测量仪器-B1500A半导体参数分析仪

一台抵得上多种测量仪器-B1500A半导体参数分析仪 B1500A 半导体器件分析仪 卓越的测量能力&#xff0c; 完美的一体化解决方案&#xff0c; 经济高效, 出色的软件。 #B1500A 3步表征设备 使用B1500A半导体参数分析仪或PC上随附的EasyEXPERT group 表征软件。EasyEXPERT …

如何卸载在linux下通过rpm安装的mysql

目录 1.先关闭MySQL服务并查看运行状态 2.使用 rpm 管道命令的方式查看已安装的mysql 3. 使用rpm -ev 命令移除安装 4. 删除MySQL数据库内容 1.先关闭MySQL服务并查看运行状态 如果之前安装过并已经启动&#xff0c;则需要卸载前请先关闭MySQL服务 systemctl stop mysqld…

Juniper Networks Junos OS EX远程命令执行漏洞(CVE-2023-36845)

Juniper Networks Junos OS EX远程命令执行漏洞&#xff08;CVE-2023-36845&#xff09; 免责声明漏洞描述漏洞影响漏洞危害网络测绘Fofa: body"J-web" || title"Juniper Web Device Manager" 漏洞复现1. 构造poc2. 查看文件3. 执行命令 免责声明 仅用于技…

【编译原理】LL(1)文法

文章目录 语法分析基本概念自上而下语法分析自上而下语法分析的问题 消除文法左递归消除直接左递归消除间接左递归消除左递归的算法 解决回溯问题FIRST集与提出公共左因子FIRST集提取左公共因子 FOLLOW集合 构造FIRST集和FOLLOW集构造FIRST集合构造每个文法符号的FIRST集合构造…

新书稿费终于下来了!你猜有多少?

我的新书《从零开始学ARM》从正式出版到现在已经有半年时间了&#xff01; 第一批印刷的几千册已经基本销售完&#xff0c; 第二版会对其中勘误进行修正&#xff0c;并继续继续印刷。 前两年写书、审稿&#xff0c; 所有业余时间都耗在这上面了&#xff0c; 在下面这篇文章…

人大金仓KingbaseES_V008R006C008B0014安装

人大金仓安装 一、安装前准备工作 1、硬件环境要求 KingbaseES支持通用X86_64、龙芯、飞腾、鲲鹏等国产CPU硬件体系架构。 2、软件环境要求 KingbaseES支持各种主流的Linux操作系统64位发行版本&#xff0c;包括CentOS、中标麒麟、银河麒麟、统信UOS、Deepin、凝思、中科方…

基于springboot+vue开发的教师工作量管理系

教师工作量管理系 springboot31 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了教师工作量管理系统的开发全过程。通过分析教师工作量管理系统管理的不足&#xff0c;创建了一个计算机管理教师工作量管理系…

EtherCAT转EtherNET/IP协议网关控制EtherCAT伺服驱动器的方法

只需一步&#xff0c;将你的EtherCAT协议设备转换为EthernetIP协议&#xff01; 捷米特JM-ECTM-EIP网关&#xff0c;这款专为EtherCAT协议设备设计的转接装置&#xff0c;可以轻松地将EtherCAT设备数据采集的数据转换成EthernetIP协议。而且&#xff0c;我们的网关接口非常灵活…