SpringCloud Alibaba - Sentinel篇

1. Sentinel のクイック スタート


画像-20230920210017106

Sentinel公式サイトアドレス:https://sentinelguard.io/zh-cn/index.html

Sentinel プロジェクトのアドレス: https://github.com/alibaba/Sentinel

Sentinel は、Alibaba がオープンソース化したマイクロサービス トラフィック管理コンポーネントであり、主にトラフィックをエントリ ポイントとして使用して、開発者がトラフィック制限、サーキット ブレーカーの低下、システム負荷保護などの多面からマイクロサービスの安定性を確保できるようにします。(ベンチマーク製品: Springcloud Hystrix Porcupine)

Sentinel は 2 つの部分に分かれています。

  • コア ライブラリ (Java クライアント) : この jar パッケージはフレームワークに依存せず、Java 8 以降で実行でき、Dubbo/Spring Cloud などのフレームワークも適切にサポートしています。
  • ダッシュボード: Sentinel フレームワークの管理センターに相当し、グラフィカル インターフェイスを通じて Sentinel の設定と監視 (サービスのトラフィック、リクエスト、応答、その他の指標を監視できます) やその他の操作を行うことができ、安全性をより確実に確保できます。アプリケーションの安定性と信頼性。

画像-20230920213830678

2 つのヒューズ フレームの比較:

関数 センチネル ヒストリックス (ヤマアラシの兄弟)
スレッドの分離 セマフォの分離 スレッドプール分離/セマフォ分離
サーキットブレーカー戦略 スローコール比率または異常比率に基づく 異常な比率に基づいて
制限する QPSに基づいて、トラフィックシェーピングをサポート 限定的なサポート
後退する サポート サポート
コンソール すぐに使用できるルールの設定、第 2 レベルの監視、マシン検出などの表示を行うことができます。 不完全
設定方法 コンソールによると、再起動後に失敗します。 注釈または設定ファイルに基づいて、永続的に有効になります

1. Sentinel ダッシュボード コンソールを起動します。


視覚化することでSentinelの操作が容易になります。

1. Sentinel-dashboard の jar パッケージをダウンロードします: https://github.com/alibaba/Sentinel/releases/tag/1.8.6

画像-20230921001906722

2. コマンドラインで jar を実行してコンソールを起動します (または、イメージをビルドしてコンテナーにスローして開始します)。

java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar

パラメータの紹介:

  • -Dserver.port=8090: Sentinel コンソール プログラムのポートを 8090 に指定します。

  • -Dcsp.sentinel.dashboard.server=localhost:8090: Sentinel コンソールのアクセス アドレス。クライアントはこのアドレスにハートビート パケットを自動的に送信します。

  • -Dproject.name=sentinel-dashboard: Sentinel コンソール プログラムで表示される名前を指定します。

  • ドキュメントアドレス: https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9

画像-20230921004704830

3. Sentinel のコンソールにアクセスします: http://localhost:8090/、デフォルトのアカウント/パスワード: どちらも Sentinel です。

画像-20230921005003769

ログインに成功すると、コンソールの内部情報を表示できます。デフォルトでは、sentinel-dashboard サービス自体が監視されます。

画像-20230921005247618

画像-20230921005457889

画像-20230921005524797


2. マイクロサービス環境の構築


データベースの準備:

CREATE DATABASE cloud_demo DEFAULT CHARACTER SET utf8mb4;

use cloud_demo;

DROP TABLE IF EXISTS `tb_user`;

CREATE TABLE `tb_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人',
  `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

INSERT INTO `tb_user` VALUES (1, '潘掌柜', '黑龙江省牡丹江市');
INSERT INTO `tb_user` VALUES (2, '文二狗', '陕西省西安市');
INSERT INTO `tb_user` VALUES (3, '华沉鱼', '湖北省十堰市');
INSERT INTO `tb_user` VALUES (4, '张必沉', '天津市');
INSERT INTO `tb_user` VALUES (5, '郑爽爽', '辽宁省沈阳市大东区');
INSERT INTO `tb_user` VALUES (6, 'kunkun', '山东省青岛市');


DROP TABLE IF EXISTS `tb_order`;

CREATE TABLE `tb_order`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单id',
  `user_id` bigint(20) NOT NULL COMMENT '用户id',
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名称',
  `price` bigint(20) NOT NULL COMMENT '商品价格',
  `num` int(10) NULL DEFAULT 0 COMMENT '商品数量',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

INSERT INTO `tb_order` VALUES (101, 1, 'Apple 苹果 iPhone 12 ', 699900, 1);
INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新国标电动车', 209900, 1);
INSERT INTO `tb_order` VALUES (103, 3, '骆驼(CAMEL)休闲运动鞋女', 43900, 1);
INSERT INTO `tb_order` VALUES (104, 4, '小米10 双模5G 骁龙865', 359900, 1);
INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 双模5G 视频双防抖', 299900, 1);
INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷静星II ', 544900, 1);
INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人体工学电脑椅子', 79900, 1);
INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休闲男鞋', 31900, 1);

画像-20230921020130649


2.1 親プロジェクトの作成

スプリングブート バージョン 2.7.12、スプリングクラウド バージョン 2021.0.3。

Maven プロジェクトを作成し、src ディレクトリを削除し、いくつかの依存関係を pom ファイルに導入します。

画像-20230921011829295

画像-20230921012711687

<?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>cn.z3inc</groupId>
    <artifactId>sentinel-demo</artifactId>
    <packaging>pom</packaging><!--pom代表聚合工程-->
    <version>1.0</version>

    <!-- springboot工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <org.projectlombok.version>1.18.20</org.projectlombok.version>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
        <mybatis-plus.version>3.4.3</mybatis-plus.version>
        <hutool.version>5.8.11</hutool.version>
        <mysql.version>8.0.23</mysql.version>
    </properties>

    <!-- 对依赖包进行管理 -->
    <dependencyManagement>
        <dependencies>
            <!-- spring cloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- spring cloud alibaba -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 数据库驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!-- mybatis plus -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <!-- hutool工具类 -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.version}</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

   <build>
    <plugins>
        <!--打包跳过单元测试-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
    </plugins>
</build>
    
</project>

2.2 ユーザーマイクロサービスの作成

1. ユーザーモジュールの作成

画像-20230921013420839

2. 依存関係を導入します。

<?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>cn.z3inc</groupId>
        <artifactId>sentinel-demo</artifactId>
        <version>1.0</version>
    </parent>

    <artifactId>user-service</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--nacos注册中心依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--springmvc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mp-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--hutool工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
    </dependencies>

    <!--打包插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. application.yml ファイル構成を書き込みます。

server:
  port: 9001

spring:
  application:
    name: user-service #服务名称
  cloud:
    nacos:
      # nacos注册中心配置
      discovery:
        server-addr: 127.0.0.1:8848 #nacos服务器地址
  # 数据库配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

# mp配置
mybatis-plus:
  mmapper-locations: classpath:mapper/*.xml #mapper配置文件存放路径
  type-aliases-package: cn.z3inc.user.pojo # 类型别名(实体类所在包)
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #配置标准sql输出
    map-underscore-to-camel-case: true #开启驼峰映射

#日志级别
logging:
  level:
    cn.z3inc: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS # 格式化输出日期


4. スタートアップ クラスを作成します。

@SpringBootApplication
@MapperScan("cn.z3inc.user.mapper")
public class UserServiceApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

5. ライティング業務:

エンティティクラス:

package cn.z3inc.user.pojo;

import lombok.Data;

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}

マッパーインターフェイス:

package cn.z3inc.user.mapper;

import cn.z3inc.user.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    
    
    
}

サービスインターフェース:

package cn.z3inc.user.service;

import cn.z3inc.user.pojo.User;
import com.baomidou.mybatisplus.extension.service.IService;

public interface UserService extends IService<User> {
    
    
}
package cn.z3inc.user.service.impl;

import cn.z3inc.user.mapper.UserMapper;
import cn.z3inc.user.pojo.User;
import cn.z3inc.user.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    
}

コントローラ:

package cn.z3inc.user.controller;

import cn.z3inc.user.pojo.User;
import cn.z3inc.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {
    
    

    @Autowired
    private UserService userService;

    /**
     * 根据ID获取用户信息
     *
     * @param id 用户ID
     * @return
     */
    @GetMapping("/{id}")
    public User findById(@PathVariable("id") Long id) {
    
    
        return userService.getById(id);
    }

    /**
     * 修改用户信息
     *
     * @param user 用户信息
     */
    @PutMapping("/update")
    public void updateUser(@RequestBody User user) {
    
    
        userService.updateById(user);
    }

    /**
     * 根据ID删除用户
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable("id") Long id) {
    
    
        userService.removeById(id);
    }

    /**
     *  新增用户
     * @param user
     */
    @PostMapping("/save")
    public void saveUser(@RequestBody User user) {
    
    
        userService.save(user);        
    }
}

画像-20230921153653979

6. nacos とユーザー マイクロサービスのテストを開始する

.\startup.cmd -m standalone

画像-20230921102040129

画像-20230921154742489


2.3 注文マイクロサービスの作成

1. 注文モジュールの作成

画像-20230921155433895

2. 依存関係を導入します。

<?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>cn.z3inc</groupId>
        <artifactId>sentinel-demo</artifactId>
        <version>1.0</version>
    </parent>

    <artifactId>order-service</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- openfeign 微服务远程调用  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- loadbalancer 实现客户端做负载均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--nacos注册中心依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--springmvc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mp-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--hutool工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
    </dependencies>

    <!--打包插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3. application.yml 設定を書き込みます。

server:
  port: 9001

spring:
  application:
    name: user-service #服务名称
  cloud:
    nacos:
      # nacos注册中心配置
      discovery:
        server-addr: 127.0.0.1:8848 #nacos服务器地址
  # 数据库配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

# mp配置
mybatis-plus:
  mmapper-locations: classpath:mapper/*.xml #mapper配置文件存放路径
  type-aliases-package: cn.z3inc.order.pojo # 类型别名(实体类所在包)
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #配置标准sql输出
    map-underscore-to-camel-case: true #开启驼峰映射
  global-config:
    db-config:
      id-type: auto # 主键策略
      table-prefix: tb_ # 表名前缀配置

#日志级别
logging:
  level:
    cn.z3inc: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS # 格式化输出日期

4. スタートアップ クラスを作成します。

package cn.z3inc.order;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;


@EnableFeignClients(basePackages = "cn.z3inc.order.feign") //开启feign远程调用
@SpringBootApplication
@MapperScan("cn.z3inc.order.mapper")
public class OrderServiceApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

5. ライティング業務:

エンティティクラス:

//用户实体
@Data
public class User {
    
    
    private Long id;
    private String username;
    private String address;
}

// 订单实体
@Data
public class Order {
    
    
    private Long id;
    private String name;
    private Long price;
    private Integer num;
    private Long userId;
    @TableField(exist = false) // 排除数据表中不存在的字段
    private User user;
}

マッパーインターフェイス:

package cn.z3inc.order.mapper;

import cn.z3inc.order.pojo.Order;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface OrderMapper extends BaseMapper<Order> {
    
    

}

サービスインターフェース:

package cn.z3inc.order.service;

import cn.z3inc.order.pojo.Order;
import com.baomidou.mybatisplus.extension.service.IService;

public interface OrderService extends IService<Order> {
    
    
    //根据id查订单
    Order findById(Long id);
}

偽のインターフェイス:

package cn.z3inc.order.feign;

import cn.z3inc.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 *  用户服务Feign接口
 */
@FeignClient("user-service")//指定要调用的服务名称
public interface UserClient {
    
    

    /*
        主要是基于SpringMVC的注解来声明远程调用的信息,比如:
            - 服务名称:userservice
            - 请求方式:GET
            - 请求路径:/user/{id}
            - 请求参数:Long id
            - 返回值类型:User
     */

    // 定义远程调用方法
    // 通过id查用户
    @GetMapping("/user/{id}") //调用对应controller的方法路径
    User findById(@PathVariable("id") Long id);// @PathVariable注解一定要指定参数名称,否则会报错
}

サービスインターフェース実装クラス:

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    
    

    @Autowired
    private UserClient userClient;

    @Override
    public Order findById(Long id) {
    
    
        Order order = super.getById(id);
        User user = userClient.findById(order.getUserId());//微服务远程调用
        order.setUser(user);
        return order;
    }
}

コントローラ:

package cn.z3inc.order.controller;

import cn.z3inc.order.pojo.Order;
import cn.z3inc.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/order")
public class OrderController {
    
    

    @Autowired
    private OrderService orderService;

    @GetMapping("/{orderId}")
    public Order findById(@PathVariable("orderId") Long orderId) {
    
    
        return orderService.findById(orderId);
    }
}

6. テスト:

画像-20230921163715671


2.4 ゲートウェイマイクロサービスの構築

1. ゲートウェイモジュールを作成する

画像-20230921164143848

2. 依存関係を導入します。

<dependencies>
    <!--gateway网关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--loadbalancer代替ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    <!--nacos注册中心-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

3. application.yml 構成を変更します。

server:
  port: 10010 # 网关的服务端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务地址
    # 网关的配置
    gateway:
      # 跨域配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowed-origin-patterns: "*"
            allowed-headers: "*"
            allow-credentials: true
            allowed-methods:
              - GET
              - POST
              - DELETE
              - PUT
              - OPTION
      # 网关路由配置        
      routes: 
        - id: user-service # 路由id    
          uri: lb://user-service # 路由地址
          predicates: # 路由断言(匹配规则)
            - Path=/user/** 
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

4. スタートアップ クラスを作成します。

package cn.z3inc.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

画像-20230921202520666

5. テスト:

画像-20230921202050740

画像-20230921202210196


3.センチネルを統合する


注文マイクロサービスにセンチネルの依存関係を導入し、監視のためにセンチネル ダッシュボード コンソールに接続します。

1. センチネルの依存関係を導入します。

<!--sentinel-->
<dependency>
    <groupId>com.alibaba.cloud</groupId> 
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2. 注文サービスの application.yml ファイルを変更し、Sentinel コンソール設定を追加します。

spring:
  cloud: 
    sentinel:
      transport:
        dashboard: localhost:8090 #控制台地址
      http-method-specify: true #开启请求方式前缀  

画像-20230922212832817

3. 注文マイクロサービスを再起動します

4. 注文マイクロサービス インターフェイスにアクセスします: http://localhost:9002/order/102

5. Sentinel-dashboard コンソールにアクセスして、オーダー サービス リクエストのリソースを表示します: http://localhost:8090

画像-20230922113918905

画像-20230922113445998

クラスター ポイント リンク: プロジェクト内の呼び出しリンクです。リンク内の Sentinel によって監視される各インターフェイスはリソースです。デフォルトでは、Sentinel は SpringMVC の各エンドポイント (http インターフェース) を監視します。電流制限、サーキット ブレーカーなどはすべてクラスター ポイント リンク内のリソースに設定され、リソース名はインターフェイスのリクエスト パスにデフォルトで設定されます。


2. 電流制限を要求する


リクエスト電流制限: トラフィックの急増によるサービス障害を回避するために、アクセス インターフェイスへの同時リクエストの数を制限します。

これはセンチネル コンソールでも設定されており、指定したクラスター ポイント リンクの後ろにあるフロー制御ボタンをクリックして、電流制限処理を実行します。

画像-20230922120334138

画像-20230922120746025


JMeter を使用してストレス テストを実行します。

(1) テスト計画用のスレッドグループを作成する

画像-20230922124550510

画像-20230922125347750

(2) http サンプラーをスレッド グループに追加します。

画像-20230922125853615

画像-20230922130155922

(3) http サンプラーのリスニング レポートを追加します。

画像-20230922130423316

(4) http サンプラーのビュー結果ツリーを追加します。

画像-20230922130624205

(5) テストの実行

画像-20230922131029049

画像-20230922131235248

画像-20230922132722842


最後に、コンソールで監視結果を確認します。

画像-20230922131159127

このインターフェイスでは、合格した QPS が 6 で、拒否された QPS が 4 であることがわかります。これは予想と一致しています。


3. スレッドの分離


電流制限により、サーバーの負荷が軽減され、同時トラフィックによって引き起こされるサービス障害の可能性を最小限に抑えることができますが、サービス障害を完全に回避することはできません。サービスに障害が発生すると、雪崩を避けるためにこのサービスへの呼び出しを分離する必要があります。

スレッド分離: バルクヘッド モードとも呼ばれ、キャビン パーティションの防水原理をシミュレートします。各業務が使用するスレッド数を制限することで、障害が発生した業務を隔離し、障害の拡大を防ぎます。(利点: サービスがクラッシュして一部のスレッドが失われた場合でも、Tomcat リソース全体には影響しません)

画像-20230922134001388


1. OpenFeign は Sentinel を統合します


注文サービスの FeignClient インターフェイスのスレッド分離を実装します。

注文サービスの application.yml ファイルを変更し、Feign のセンチネル機能を有効にするように構成します。

feign:
  sentinel:
    enabled: true # 开启feign对sentinel的支持

画像-20230922135021576

注文サービスを再起動すると、クエリ ユーザーの FeignClient が自動的にクラスター ポイント リソースになることがわかります。

画像-20230922135404445


2. スレッド分離を構成する


ユーザー偽装インターフェイスをクエリするクラスター ポイント リソースの同時スレッド数を構成します: (最大 5 つのスレッドを使用できます)

画像-20230922140117810

画像-20230922135836861

画像-20230922200857542

JMeter テスト スクリプトを実行し、1 秒あたり 100 リクエストを送信します。

画像-20230922140908719

テスト結果は次のとおりです。

画像-20230922195816752


4. サービスサーキットブレーカー


サービス サーキット ブレーカー:サーキット ブレーカーは、異常なリクエストの割合または低速な呼び出しの割合をカウントし、しきい値を超えるとサービスがサーキット ブレーカーとなり、インターフェイスへのリクエストが遮断されます。サーキット ブレーカー期間中、すべてのリクエストはすぐに失敗し、現在のサービスへの影響を避けるためにフォールバック ロジックが使用されます。(Hystrix Porcupine のアプローチ: 偽インターフェイスを調整できない場合は、偽インターフェイス実装クラスのロジックを使用してサービス雪崩を回避します)

画像-20230923144019242


1. ダウングレードロジックを作成する


ヤマアラシ兄弟の使い方と似ています。

電流制限やサーキット ブレーカーをトリガーするリクエストは、必ずしもエラーを直接報告する必要はありません。一部のデフォルト データやわかりやすいプロンプトを返すこともでき、これによりユーザー エクスペリエンスが向上します。

FeignClient の障害後にダウングレード ロジックを作成するには、通常 2 つの方法があります。

  • 方法 1: FallbackClass はリモート呼び出しの例外を処理できません。
  • 方法 2: FallbackFactory。リモート呼び出しで例外を処理できます (推奨)。

1. オーダーサービスのUserClientにダウングレード処理クラスを定義し、FallbackFactoryインターフェースを実装します。

package cn.z3inc.order.fallback;

import cn.z3inc.order.feign.UserClient;
import cn.z3inc.order.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;

/**
 * UserClient降级处理类
 *
 */
@Slf4j
public class UserClientFallback implements FallbackFactory<UserClient> {
    
    

    // 定义userclient降级逻辑
    @Override
    public UserClient create(Throwable cause) {
    
    
        return new UserClient(){
    
    
            @Override
            public User findById(Long id) {
    
     
                log.error("远程调用UserClient#findById方法出现异常,参数:{}", id, cause);
                return new User();
            }
        };
    }
}

画像-20230923151519698

2. 構成クラスを作成し、UserClientFallback を Bean として登録します。

package cn.z3inc.order.config;

import cn.z3inc.order.fallback.UserClientFallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;

@Slf4j
public class DefaultFeignConfig {
    
    
    
    @Bean
    public UserClientFallback userClientFallback() {
    
    
        return new UserClientFallback();
    }
}

3. UserClient で作成した縮退処理クラスを構成します。

/**
 *  用户服务Feign接口
 */
@FeignClient(value = "user-service", //指定要调用的服务名称
        configuration = DefaultFeignConfig.class, // 指定Feign的配置类
        fallbackFactory = UserClientFallback.class // 指定回退工厂类
)
public interface UserClient {
    
    

画像-20230923152127413

4. 注文サービスを再起動し、ユーザー サービスを停止してテストします。

画像-20230923152307420


2. サービスサーキットブレーカー


リモートで呼び出されたサービスがハングアップすると、現在のサービスへの影響を避けるためにダウングレード ロジックが直接使用されます。それは、擬似インターフェースを融合することですリモート呼び出しサービスが通常に戻ると、インターフェイスの呼び出しが許可されます。これは実際にはサーキットブレーカーの動作モードです。

Sentinel のサーキット ブレーカーは、特定のインターフェイス上の低速リクエストの割合をカウントするだけでなく、異常なリクエストの割合もカウントします。これらの比率がしきい値を超えると、インターフェイスは切断されますつまり、インターフェイスにアクセスするすべてのリクエストが傍受され、ダウングレードされます。インターフェイスが通常に戻ると、インターフェイスに対するリクエストは解放されます。
サーキット ブレーカーの動作状態の切り替えはステート マシンによって制御されます。

ステート マシンには次の 3 つの状態が含まれます。

  • Closed : 閉状態の場合、サーキット ブレーカーはすべてのリクエストを解放し、異常比率と低速リクエスト比率のカウントを開始します。閾値を超えるとオープン状態に切り替わります。
  • open : オープン状態では、サービス呼び出しはサーキットブレーカーであり、サーキットブレーカーサービスへのアクセス要求は拒否され、すぐに失敗し、ダウングレードロジックに直接進みます。オープン状態が一定時間続くとハーフオープン状態になります。
  • ハーフオープン: ハーフオープン状態、リクエストを解放し、実行結果に基づいて次の動作を判断します。
    • リクエストは成功しました: クローズ状態に切り替えます
    • リクエストは失敗します: オープン状態に切り替えます

クラスター ポイント リンクの後ろにあるボタンをクリックすることで、コンソールでサーキット ブレーカー戦略を構成できます熔断(永続性を nacos 構成ファイルに書き込む必要があります)。

画像-20230923153302326

画像-20230923153424668

これは、遅い呼び出しの比率に基づいて行われます。上記の設定の意味は次のとおりです。

  • RT が 200 ミリ秒を超えるリクエスト コールは低速コールです。
  • 最後の 1000 ミリ秒で少なくとも 5 つのリクエストをカウントします。低速呼び出し率が 0.5 以上の場合、サーキット ブレーカーがトリガーされます。
  • サーキットブレーカーの持続時間は20秒です

jmeter を使用してテストします。

画像-20230923154511253

画像-20230923154811934

おすすめ

転載: blog.csdn.net/qq_46921028/article/details/133208704