Rubin's Blog

  • 首页
  • 关于作者
  • 隐私政策
享受恬静与美好~~~
分享生活的点点滴滴~~~
  1. 首页
  2. SpringCloud
  3. 正文

SpringCloud Alibaba之微服务开发

2021年 10月 25日 596点热度 0人点赞 0条评论

前言

我们本博文主要讲解一下SpringCloud Alibaba的使用方法。通过Nacos + Sentinel + Dubbo的架构方式来搭建一个微服务架子。

Nacos搭建

参看博文:SpringCloud Alibaba之Nacos。

Sentinel Dashboard搭建

参看博文: SpringCloud Alibaba之Sentinel。

搭建父工程

我们创建一个Maven项目spring-cloud-demo,其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>

    <!--spring boot 父启动器依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <groupId>com.rubin</groupId>
    <artifactId>spring-cloud-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>sca</module>
    </modules>
    <packaging>pom</packaging>

    <dependencies>
        <!--日志依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <!--测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok⼯具-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <!-- Actuator可以帮助你监控和管理Spring Boot应用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <!--SCA -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--SCA -->
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <!--打包插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

在其下面创建子模块sca,其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>spring-cloud-demo</artifactId>
        <groupId>com.rubin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <modules>
        <module>sca-service-common</module>
        <module>sca-service-resume</module>
        <module>sca-service-auto-deliver</module>
    </modules>

    <artifactId>sca</artifactId>


</project>

创建公用服务

在sca模块下创建公用模块sca-service-common,其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>sca</artifactId>
        <groupId>com.rubin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sca-service-common</artifactId>
    <packaging>pom</packaging>

    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

服务提供者

在sca模块下创建服务提供者模块sca-service-resume,其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>sca</artifactId>
        <groupId>com.rubin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sca-service-resume</artifactId>

    <dependencies>
        <!--spring cloud alibaba dubbo 依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-apache-dubbo-adapter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.rubin</groupId>
            <artifactId>sca-service-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

</project>

创建数据库spring_cloud_db,导入如下SQL:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for r_resume
-- ----------------------------
DROP TABLE IF EXISTS `r_resume`;
CREATE TABLE `r_resume` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sex` varchar(10) DEFAULT NULL COMMENT '性别',
  `birthday` varchar(30) DEFAULT NULL COMMENT '出生日期',
  `work_year` varchar(100) DEFAULT NULL COMMENT '工作年限',
  `phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
  `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
  `status` varchar(80) DEFAULT NULL COMMENT '目前状态',
  `resume_name` varchar(500) DEFAULT NULL COMMENT '简历名称',
  `name` varchar(40) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL COMMENT '创建日期',
  `head_pic` varchar(100) DEFAULT NULL COMMENT '头像',
  `is_del` int(2) DEFAULT NULL COMMENT '是否删除 默认值0-未删除 1-已删除',
  `update_time` datetime DEFAULT NULL COMMENT '简历更新时间',
  `user_id` int(11) DEFAULT NULL COMMENT '用户ID',
  `is_default` int(2) DEFAULT NULL COMMENT '是否为默认简历 0-默认 1-非默认',
  `highest_education` varchar(20) DEFAULT '' COMMENT '最高学历',
  `deliver_near_by_confirm` int(2) DEFAULT '0' COMMENT '投递附件简历确认 0-需要确认 1-不需要确认',
  `refuse_count` int(11) NOT NULL DEFAULT '0' COMMENT '简历被拒绝次数',
  `mark_can_interview_count` int(11) NOT NULL DEFAULT '0' COMMENT '被标记为可面试次数',
  `have_notice_inter_count` int(11) NOT NULL DEFAULT '0' COMMENT '已通知面试次数',
  `one_word` varchar(100) DEFAULT '' COMMENT '一句话介绍自己',
  `live_city` varchar(100) DEFAULT '' COMMENT '居住城市',
  `resume_score` int(3) DEFAULT NULL COMMENT '简历得分',
  `user_identity` int(1) DEFAULT '0' COMMENT '用户身份1-学生 2-工人',
  `is_open_resume` int(1) DEFAULT '3' COMMENT '人才搜索-开放简历 0-关闭,1-打开,2-简历未达到投放标准被动关闭 3-从未设置过开放简历',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2195388 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of r_resume
-- ----------------------------
BEGIN;
INSERT INTO `r_resume` VALUES (2195320, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-24 13:40:14', 'images/myresume/default_headpic.png', 0, '2015-04-24 13:40:14', 1545132, 1, '本科', 0, 0, 0, 0, '', '广州', 15, 0, 3);
INSERT INTO `r_resume` VALUES (2195321, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-24 14:17:54', 'images/myresume/default_headpic.png', 0, '2015-04-24 14:20:35', 1545133, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195322, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-24 14:42:45', 'images/myresume/default_headpic.png', 0, '2015-04-24 14:43:34', 1545135, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195323, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-24 14:48:19', 'images/myresume/default_headpic.png', 0, '2015-04-24 14:50:34', 1545136, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195331, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-24 18:43:35', 'images/myresume/default_headpic.png', 0, '2015-04-24 18:44:08', 1545145, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195333, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-24 19:01:13', 'images/myresume/default_headpic.png', 0, '2015-04-24 19:01:14', 1545148, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195336, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-27 14:13:02', 'images/myresume/default_headpic.png', 0, '2015-04-27 14:13:02', 1545155, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195337, '女', '1990', '2年', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿的简历', 'wps', '2015-04-27 14:36:55', 'images/myresume/default_headpic.png', 0, '2015-04-27 14:36:55', 1545158, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195369, '女', '1990', '10年以上', '199999999', 'test@testtest01.com', '我目前已离职,可快速到岗', '稻壳儿', 'wps', '2015-05-15 18:08:19', 'images/myresume/default_headpic.png', 0, '2015-05-15 18:08:19', 1545346, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195374, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 17:53:37', 'images/myresume/default_headpic.png', 0, '2015-06-04 17:53:39', 1545523, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195375, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:11:06', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:11:07', 1545524, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195376, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:12:19', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:12:19', 1545525, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195377, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:13:28', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:13:28', 1545526, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195378, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:15:16', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:15:16', 1545527, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195379, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:23:06', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:23:06', 1545528, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195380, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:23:38', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:23:39', 1545529, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195381, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:27:33', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:27:33', 1545530, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195382, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:31:36', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:31:39', 1545531, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195383, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 18:36:48', 'images/myresume/default_headpic.png', 0, '2015-06-04 18:36:48', 1545532, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195384, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 19:15:15', 'images/myresume/default_headpic.png', 0, '2015-06-04 19:15:16', 1545533, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195385, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 19:28:53', 'images/myresume/default_headpic.png', 0, '2015-06-04 19:28:53', 1545534, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195386, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 19:46:42', 'images/myresume/default_headpic.png', 0, '2015-06-04 19:46:45', 1545535, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
INSERT INTO `r_resume` VALUES (2195387, '女', '1990', '1年', '199999999', 'test@testtest01.com', '我目前正在职,正考虑换个新环境', '稻壳儿', 'wps', '2015-06-04 19:48:16', 'images/myresume/default_headpic.png', 0, '2015-06-04 19:48:16', 1545536, 1, '本科', 0, 0, 0, 0, '', '广州', 65, 0, 3);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

创建配置文件bootstrap.yml如下:

spring:
  application:
    name: sca-service-resume
  cloud:
    nacos:
      discovery:
        # 配置nacos server地址
        server-addr: nacos-host:8848
        namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
      config:
        server-addr: nacos-host:8848
        namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
        prefix: sca-service-resume
        group: DEFAULT_GROUP
        file-extension: yaml
        ext-config[0]:
          data-id: actuator.yaml
          group: DEFAULT_GROUP
          refresh: true

在Nacos里面创建配置文件sca-service-resume.yaml:

server:
  port: 9010
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/spring_cloud_db?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
  main:
    allow-bean-definition-overriding: true  

dubbo:
  scan:
    # dubbo 服务扫描基准包
    base-packages: com.rubin.sca.service.resume.service
  protocol:
    # dubbo 协议
    name: dubbo
    # dubbo 协议端口( -1 表示自增端口,从 20880 开始)
    port: -1
  registry:
    # 挂载到 Spring Cloud 的注册中心
    address: spring-cloud://localhost

创建actuator.yaml如下:

# springboot中暴露健康检查等断点接口
management:
  endpoints:
    web:
      exposure:
        include: "*"
  # 暴露健康接口的细节
  endpoint:
    health:
      show-details: always

创建启动类:

package com.rubin.sca.service.resume;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan(basePackages = "com.rubin.sca.service.resume.mapper")
public class ScaServiceResumeBootstrap {

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

}

在sca-service-common里面创建公用实体和共用接口:

package com.rubin.sca.service.common.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * <p>
 * 
 * </p>
 *
 * @author rubin
 * @since 2021-09-29
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class RResume implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 性别
     */
    private String sex;

    /**
     * 出生日期
     */
    private String birthday;

    /**
     * 工作年限
     */
    private String workYear;

    /**
     * 手机号码
     */
    private String phone;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 目前状态
     */
    private String status;

    /**
     * 简历名称
     */
    private String resumeName;

    private String name;

    /**
     * 创建日期
     */
    private LocalDateTime createTime;

    /**
     * 头像
     */
    private String headPic;

    /**
     * 是否删除 默认值0-未删除 1-已删除
     */
    private Integer isDel;

    /**
     * 简历更新时间
     */
    private LocalDateTime updateTime;

    /**
     * 用户ID
     */
    private Integer userId;

    /**
     * 是否为默认简历 0-默认 1-非默认
     */
    private Integer isDefault;

    /**
     * 最高学历
     */
    private String highestEducation;

    /**
     * 投递附件简历确认 0-需要确认 1-不需要确认
     */
    private Integer deliverNearByConfirm;

    /**
     * 简历被拒绝次数
     */
    private Integer refuseCount;

    /**
     * 被标记为可面试次数
     */
    private Integer markCanInterviewCount;

    /**
     * 已通知面试次数
     */
    private Integer haveNoticeInterCount;

    /**
     * 一句话介绍自己
     */
    private String oneWord;

    /**
     * 居住城市
     */
    private String liveCity;

    /**
     * 简历得分
     */
    private Integer resumeScore;

    /**
     * 用户身份1-学生 2-工人
     */
    private Integer userIdentity;

    /**
     * 人才搜索-开放简历 0-关闭,1-打开,2-简历未达到投放标准被动关闭 3-从未设置过开放简历
     */
    private Integer isOpenResume;

}
package com.rubin.sca.service.common.service;

import com.rubin.sca.service.common.entity.RResume;

import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author rubin
 * @since 2021-09-29
 */
public interface IRResumeService {

    String hello();

    List<RResume> getResumes();

    RResume getResumeDetail(Long userId);

    String timeout() throws InterruptedException;

}

创建dao层:

package com.rubin.sca.service.resume.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rubin.sca.service.common.entity.RResume;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author rubin
 * @since 2021-09-29
 */
public interface RResumeMapper extends BaseMapper<RResume> {

}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rubin.sca.service.resume.mapper.RResumeMapper">

</mapper>

service层:

package com.rubin.sca.service.resume.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rubin.sca.service.common.entity.RResume;
import com.rubin.sca.service.common.service.IRResumeService;
import com.rubin.sca.service.resume.mapper.RResumeMapper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Value;

import java.util.List;
import java.util.Random;

@Service
public class ResumeServiceImpl extends ServiceImpl<RResumeMapper, RResume> implements IRResumeService, IService<RResume> {

    private static final Random random = new Random();

    @Value("${server.port}")
    private Integer port;

    @Override
    public String hello() {
        return "Hello! This is from port : " + port;
    }

    @Override
    public List<RResume> getResumes() {
        return list();
    }

    @Override
    public RResume getResumeDetail(Long userId) {
        QueryWrapper<RResume> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        return getOne(queryWrapper);
    }

    @Override
    public String timeout() throws InterruptedException {
        Thread.sleep(random.nextInt(2000));
        return hello();
    }

}

controller层:

package com.rubin.sca.service.resume.controller;


import com.rubin.sca.service.common.entity.RResume;
import com.rubin.sca.service.common.service.IRResumeService;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author rubin
 * @since 2021-09-29
 */
@RestController
@RequestMapping("/resume")
public class RResumeController {

    @Autowired
    private IRResumeService irResumeService;

    @GetMapping("hello")
    public String hello() {
        return irResumeService.hello();
    }

    @GetMapping("list")
    public List<RResume> getResumes() {
        return irResumeService.getResumes();
    }

    @GetMapping("detail")
    public RResume getResumeDetail(@RequestParam("userId") Long userId) {
        return irResumeService.getResumeDetail(userId);
    }

    @GetMapping("timeout")
    public String timeout() throws InterruptedException {
        return irResumeService.timeout();
    }

}

服务消费者

在sca模块下创建服务消费者模块sca-service-auto-deliver,其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>sca</artifactId>
        <groupId>com.rubin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sca-service-auto-deliver</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.rubin</groupId>
            <artifactId>sca-service-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--spring cloud alibaba dubbo 依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
        <!--sentinel 核心环境依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- Sentinel支持采用 Nacos 作为规则配置数据源,引⼊该适配依赖 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
    </dependencies>

</project>

创建配置文件bootstrap.yml如下:

spring:
  application:
    name: sca-service-auto-deliver
  cloud:
    nacos:
      discovery:
        # 配置nacos server地址
        server-addr: nacos-host:8848
        namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
      config:
        server-addr: nacos-host:8848
        namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
        prefix: sca-service-auto-deliver
        group: DEFAULT_GROUP
        file-extension: yaml
        ext-config[0]:
          data-id: actuator.yaml
          group: DEFAULT_GROUP
          refresh: true

在Nacos里面创建对应的配置文件sca-service-auto-deliver.yaml:

server:
  port: 9011
spring:
  main:
    allow-bean-definition-overriding: true
  cloud: 
    sentinel:
      transport:
        # sentinel dashboard/console地址
        dashboard: 127.0.0.1:8080
        # sentinel会在该端口启动http server,那么这样的话,控制台定义的⼀些限流等规则才能发送传递过来
        # 如果8719端口被占⽤,那么会依次+1
        port: 8719
      # Sentinel Nacos数据源配置,Nacos中的规则会⾃动同步到sentinel控制台的流控规则中  
      datasource:
        # 此处的flow为⾃定义数据源名
        # 流控规则
        flow:
          nacos:
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
            data-id: ${spring.application.name}-flow-rules.json
            groupId: DEFAULT_GROUP
            data-type: json
            # 类型来⾃RuleType类
            rule-type: flow
        degrade:
          nacos:
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
            data-id: ${spring.application.name}-degrade-rules.json
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: degrade  

dubbo:
  registry:
    # 挂载到 Spring Cloud 的注册中心
    address: spring-cloud://localhost
  cloud: 
    subscribed-services: sca-service-resume

创建启动类:

package com.rubin.autodeliver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ScaServiceAutoDeliverBootstrap {

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

}

常见controller消费消费者接口并对外提供服务:

package com.rubin.autodeliver.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.rubin.autodeliver.fallback.SentinelFallbackClass;
import com.rubin.sca.service.common.entity.RResume;
import com.rubin.sca.service.common.service.IRResumeService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Random;

@RestController
@RequestMapping("auto-deliver")
public class AutoDeliverController {

    private static final Random random = new Random();

    @Reference
    private IRResumeService irResumeService;

    @GetMapping("resume/{userId}")
    public RResume getResumeByUserId(@PathVariable("userId") Long userId) {
        return irResumeService.getResumeDetail(userId);
    }

    @GetMapping("resumes")
    public List getResumes() {
        return irResumeService.getResumes();
    }

    @GetMapping("hello")
    public String hello() {
        return irResumeService.hello();
    }

    @GetMapping("timeout")
    public String timeout() throws InterruptedException {
        return irResumeService.timeout();
    }

    @GetMapping("sentinel")
    @SentinelResource(value = "sentinel",
            blockHandlerClass = SentinelFallbackClass.class,
            blockHandler = "handleBlock",
            fallbackClass = SentinelFallbackClass.class,
            fallback = "handleException"
    )
    public String sentinel() {
        if (random.nextBoolean()) {
            int i = 3/0;
        }
        return irResumeService.hello();
    }

}

创建熔断对应的兜底方法类:

package com.rubin.autodeliver.fallback;

import com.alibaba.csp.sentinel.slots.block.BlockException;

public class SentinelFallbackClass {

    public static String handleBlock(BlockException blockException) {
        blockException.printStackTrace();
        return "被Sentinel限流了";
    }

    public static String handleException() {
        return "调用失败了,直接熔断";
    }

}

至此,我们最简单的SpringCloud Alibaba的使用案例就搭建完成了。欢迎小伙伴们积极留言交流~~~

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: SpringCloud
最后更新:2022年 6月 9日

RubinChu

一个快乐的小逗比~~~

打赏 点赞
< 上一篇

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • 前言
  • Nacos搭建
  • Sentinel Dashboard搭建
  • 搭建父工程
  • 创建公用服务
  • 服务提供者
  • 服务消费者
最新 热点 随机
最新 热点 随机
问题记录之Chrome设置屏蔽Https禁止调用Http行为 问题记录之Mac设置软链接 问题记录之JDK8连接MySQL数据库失败 面试系列之自我介绍 面试总结 算法思维
SpringCloud Alibaba之Sentinel MySQL之集群架构 MongoDB之索引 自定义简单的RPC框架 Neo4j之程序访问 RabbitMQ之集群与运维

COPYRIGHT © 2021 rubinchu.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

京ICP备19039146号-1