目录

(一)Nacos动态配置
(二)Nacos注册中心
(三)Sentinel之限流
(四)Sentinel之熔断
(五)Gateway之路由、限流
(六)Gateway之鉴权、日志
(七)Gateway搭配Nacos实现动态路由
(八)Dubbo + Nacos

正文

Nacos作为配置中心的表现可圈可点,下面继续探探作为注册中心的斤两。

上一节编写了payment-service,提供查询余额接口,现在把该服务注册到Nacos,仅需三步。

1 添加依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${alibaba.version}</version>
        </dependency>

2 配置Nacos发现服务地址

修改后的bootstrap.yml如下

spring:
  application:
    name: payment-service
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
      discovery:
        server-addr: 127.0.0.1:8848

3 在启动类上添加注解@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient
public class PaymentServiceApplication {

重新启动应用

控制台中输出

nacos registry, payment-service 192.168.12.22:8082 register finished

进入Nacos管理后台,在服务列表中已经可以看到payment-service服务(服务名为spring.application.name)

执行mvc clean package把应用打成jar包并在8082和8083端口上启动两个实例,命令如下:

java -jar payment-service-0.0.1-SNAPSHOT.jar --server.port=8082
java -jar payment-service-0.0.1-SNAPSHOT.jar --server.port=8083

 回到Nacos后台查看,可以看到两个实例信息

至此,服务Provider的工作完成,下面来写Consumer。

Consumer为账号服务,提供注册、登录等,其中部分接口需要调用payment-service服务获得余额信息合并后返回给客户端。

新建名称为account-service的SpringBoot应用,依赖、配置文件与payment-service基本相同,仅修改以下两项:

spring.application.name=account-service
server.port=8081

业务代码:

User.java

public class User {

    private int id;
    private String name;
    private Balance balance;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public User() {
    }

    //setter/getter略
}
AccountController.java
@RestController
public class AccountController {

    final static Map<Integer, User> userMap = new HashMap() {{
            put(1, new User(1, "张三"));
            put(2, new User(2, "李四"));
            put(3, new User(3, "王五"));
        }
    };

    @RequestMapping("/acc/user")
    public User getUser(@RequestParam Integer id) {
        if(id != null && userMap.containsKey(id)) {
            User user = userMap.get(id);
            return user;
        }
        return new User(0, "");
    }
}

测试

接下来添加调用payment-service服务的代码。添加相关依赖,如下:

<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
        <alibaba.version>0.9.0.RELEASE</alibaba.version>
        <spring-cloud-netflix.version>2.1.1.RELEASE</spring-cloud-netflix.version>
        <spring-cloud-openfeign.version>2.1.1.RELEASE</spring-cloud-openfeign.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${alibaba.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${alibaba.version}</version>
        </dependency>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </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>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-openfeign-dependencies</artifactId>
                <version>${spring-cloud-openfeign.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

在主类上开启Feign功能

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class AccountServiceApplication {

添加BalanceService接口

@FeignClient(name = "payment-service", fallback = BalanceServiceFallback.class)
public interface BalanceService {

    @RequestMapping(value = "/pay/balance", method = RequestMethod.GET)
    Balance getBalance(@RequestParam("id") Integer id);
}

添加BalanceServiceFallback.java

@Component
public class BalanceServiceFallback implements BalanceService {
    @Override
    public Balance getBalance(Integer id) {
        return new Balance(0, 0, 0, "降级");
    }
}

测试

返回值中已经包含balance信息。观察两个payment-service两个实例的控制台窗口,可以看到请求被平均分配。

关闭一个payment-service实例测试,服务仍然可用。那么如果两个都关闭呢?

报错了,看来程序需要继续完善,是Sentinel登场的时候了。

在account-service中添加依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>${alibaba.version}</version>
        </dependency>

在bootstrap.yml中启用

feign:
  sentinel:
    enabled: true

重启应用并测试:

降级成功。

当然,Sentinel远不止这点本事,下一节将开始它的表演。

本期源码

链接:https://pan.baidu.com/s/1DH8WhS4ttUHGMlgqKEIzxA 
提取码:anus

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐