不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • Java基础

  • 面向对象

  • Java进阶

  • Web基础

  • Spring框架

    • 01.Spring之Bean
    • 02.Spring之AOP
    • 03.SpringMVC入门
    • 04.SpringMVC案例
    • 05.SpringBoot入门
    • 06.Maven分模块开发
    • 07.MyBatisPlus
    • 08.SpringBoot案例
    • 09.SpringCloud案例
      • 01.SpringCloud事例
        • 0、服务说明
        • 1、导入Sql语句
        • 2、安装启动nacos
        • 3、访问接口
        • 4、创建项目
      • 02.代码
        • 0、项目结构
        • 1) 项目结构
        • 2) pom.xml父级
        • 1、user-service
        • 0) pom.xml
        • 1) resource
        • 2) config
        • 3) UserApplication.java
        • 4) web
        • 5) service
        • 6) mapper
        • 7) pojo
        • 2、order-service
        • 0) pom.xml
        • 1) resource
        • 2) OrderApplication.java
        • 3) web
        • 4) service
        • 5) mapper
        • 6) pojo
        • 3、feign-api
        • 0) pom.xml
        • 1) config
        • 2) clients
        • 3) pojo
        • 4、gateway
        • 0) pom.xml
        • 1) resource
        • 2) gateway
    • 10.Dubbo
  • 微服务

  • Java
  • Spring框架
xiaonaiqiang
2024-06-07
目录

09.SpringCloud案例

springcloud-demo (opens new window)

# 01.SpringCloud事例

# 0、服务说明

  • springcloud-demo:父工程,管理依赖

    • order-service:订单微服务,负责订单相关业务

    • user-service:用户微服务,负责用户相关业务

  • 要求:

    • 订单微服务和用户微服务都必须有各自的数据库,相互独立

    • 订单服务和用户服务都对外暴露Restful的接口

    • 订单服务如果需要查询用户信息,只能调用用户服务的Restful接口,不能查询用户数据库

  • SpringBoot

    • Spring Boot 是整个项目的基础框架,用于简化 Spring 应用的开发、配置和部署
  • SpringCloud

    • Spring Cloud 提供了一系列工具,帮助构建分布式系统和微服务架构
    • 服务注册与发现:通过 Eureka、Consul 或 Nacos 实现服务注册与发现
    • 配置管理:通过 Spring Cloud Config 或 Nacos 管理分布式系统的配置
    • 负载均衡:通过 Ribbon 或其他负载均衡器实现客户端负载均衡
    • 断路器:通过 Hystrix 或 Resilience4j 提供断路器功能,增强系统的容错性
    • API 网关:通过 Zuul 或 Spring Cloud Gateway 实现 API 网关功能
  • nacos

    • 配置中心:Nacos 提供动态配置服务,用于集中化管理应用配置,支持实时更新和推送
    • 服务注册与发现:Nacos 作为服务注册中心,支持服务的注册、发现和健康检查,帮助实现微服务架构
  • feign

    • 声明式 HTTP 客户端:Feign 提供了一个声明式的 HTTP 客户端,通过注解方式定义 HTTP 请求
    • 负载均衡和断路器:与 Ribbon 和 Hystrix 集成,实现客户端负载均衡和断路器功能
  • gateway

    • API 网关:Spring Cloud Gateway 提供了一种简单而有效的方式来路由和管理 API 请求
    • 路由和过滤:通过配置路由规则和过滤器,实现请求的路由、过滤和管理
    • 安全性和监控:集成安全性、监控和限流等功能,增强 API 网关的能力

# 1、导入Sql语句

# 启动MySQL
docker run --name mysql-server -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
mysql -h 127.0.0.1 -P 3306 -u root -p123456
1
2
3
  • 创建cloud_user
create database cloud_user charset utf8;
use cloud_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, '范兵兵', '山东省青岛市');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • 创建cloud_order
create database cloud_order charset utf8;
use cloud_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);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2、安装启动nacos

  • https://github.com/alibaba/nacos/releases
cd /Users/tom.xiao/soft
unzip nacos-server-2.0.3.zip 
cd nacos/bin 
vim startup.sh  # 由于电脑中安装多版本java,需要指定使用java8启动
# JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home"

sh startup.sh -m standalone
# 输出nacos is starting with standalone 即为成功
1
2
3
4
5
6
7
8
  • 访问:http://127.0.0.1:8848/nacos/#/login (账号密码都是nacos)

  • 管理命令

# 1)启动
cd /Users/tom.xiao/soft/nacos/bin
sh startup.sh -m standalone

# 2)关闭
lsof -i:8848       
kill -9 进程号

# 3)查看日志
tail /Users/tom.xiao/soft/nacos/logs/start.out
1
2
3
4
5
6
7
8
9
10

# 3、访问接口

  • http://localhost:8081/user/1/

    • {"id":1,"username":"柳岩","address":"湖南省衡阳市"}
      
      1
  • http://localhost:8088/order/101/

    • {"id":101,"price":699900,"name":"Apple 苹果 iPhone 12 ","num":1,"userId":1,"user":{"id":1,"username":"柳岩","address":"湖南省衡阳市"}}
      
      1
  • http://localhost:10010/order/101/?authorization=admin

    • {"id":101,"price":699900,"name":"Apple 苹果 iPhone 12 ","num":1,"userId":1,"user":{"id":1,"username":"柳岩","address":"湖南省衡阳市"}}
      
      1

# 4、创建项目

  • 创建一个空maven项目
  • 添加user-service模块

# 02.代码

# 0、项目结构

# 1) 项目结构

springcloud-demo
├── pom.xml
└── user-service # 一、用户服务模块(提供用户查询接口)
    ├── pom.xml
    ├── src
    │   ├── main
    │   │   ├── java
    │   │   │   └── com
    │   │   │       └── example
    │   │   │           └── user
    │   │   │               ├── UserApplication.java
    │   │   │               ├── config
    │   │   │               │   └── PatternProperties.java
    │   │   │               ├── mapper
    │   │   │               │   └── UserMapper.java
    │   │   │               ├── pojo
    │   │   │               │   └── User.java
    │   │   │               ├── service
    │   │   │               │   └── UserService.java
    │   │   │               └── web
    │   │   │                   └── UserController.java
    │   │   └── resources
    │   │       ├── application.yml
    │   │       └── bootstrap.yml
    
├── order-service # 二、订单服务模块(订单查询&调用 用户服务 查询用户信息)
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── example
│   │   │   │           └── order
│   │   │   │               ├── OrderApplication.java
│   │   │   │               ├── mapper
│   │   │   │               │   └── OrderMapper.java
│   │   │   │               ├── pojo
│   │   │   │               │   └── Order.java
│   │   │   │               ├── service
│   │   │   │               │   └── OrderService.java
│   │   │   │               └── web
│   │   │   │                   └── OrderController.java
│   │   │   └── resources
│   │   │       └── application.yml

├── feign-api  # 定义feign
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── example
│   │   │   │           └── feign
│   │   │   │               ├── clients
│   │   │   │               │   └── UserClient.java
│   │   │   │               ├── config
│   │   │   │               │   └── DefaultFeignConfiguration.java
│   │   │   │               └── pojo
│   │   │   │                   └── User.java

├── gateway  # 定义网关代理(主要在 yml中配置即可)
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── example
│   │   │   │           └── gateway
│   │   │   │               ├── AuthorizeFilter.java
│   │   │   │               └── GatewayApplication.java
│   │   │   └── resources
│   │   │       └── application.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

# 2) pom.xml父级

  • springcloud-demo/pom.xml 项目依赖管理
<?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>com.example</groupId>
    <artifactId>springcloud-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>user-service</module>
        <module>order-service</module>
        <module>feign-api</module>
        <module>gateway</module>
    </modules>
    <!--pom用于父项目或聚合项目可以告诉Maven将这些项目打包成pom文件,而不是可执行的文件-->
    <packaging>pom</packaging>

    <!--当前项目将继承Spring Boot父项目的配置,包括依赖管理、插件配置等-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.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>Hoxton.SR10</spring-cloud.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
    </properties>

    <!--用于集中管理项目的所有依赖版本,这部分的依赖版本不会自动引入到子项目中,但子项目可以引用这些依赖而不需要再次指定版本 -->
    <dependencyManagement>
        <dependencies>
            <!-- springCloud -->
            <!--这个配置不仅指定了 spring-cloud-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>
            <!--nacos的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
                <!--它只在依赖解析和执行过程中有效,但不会被包含到构建的结果中-->
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <!--没有指定版本,因为lombok通常由Spring Boot的父项目管理,所以它会从那里继承版本-->
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

# 1、user-service

# 0) pom.xml

<?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>springcloud-demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!-- nacos客户端依赖包 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--nacos的配置管理依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>
  
    <build>
        <!--用于Spring Boot应用程序的Maven项目中,以简化Spring Boot应用程序的打包-->
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

# 1) resource

  • resources/application.yml
server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/cloud_user?useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  shardingsphere: # 配置项是用于配置ShardingSphere的分片策略,但在这段代码中并未具体配置
    sharding:
      default-database-strategy:
      tables:
#      discovery:
#        cluster-name: HZ
mybatis:
  type-aliases-package: com.example.user.pojo
  configuration:
    map-underscore-to-camel-case: true #表示将数据库表中的下划线命名转换为驼峰命名
logging:
  level:
    com.example: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
#eureka:
#  client:
#    service-url:  # eureka的地址信息
#      defaultZone: http://127.0.0.1:10086/eureka
pattern:
  name: 本地环境local  # 本地环境local 配置项可能是自定义的配置,表示当前环境名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  • resources/bootstrap.yml
# 这段代码是Spring Boot应用的配置文件片段,它使用了Spring Cloud Alibaba Nacos作为配置中心和服务注册与发现的组件
spring:
  application:
    name: userservice  #设置应用名称,这个名称在微服务架构中通常用于服务发现和负载均衡
  profiles:
    active: dev # 环境
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848 # nacos地址
      config:
        file-extension: yaml # 文件后缀名
1
2
3
4
5
6
7
8
9
10
11

# 2) config

  • config/PatternProperties.java
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 当Spring Boot应用启动时,它会自动从配置文件中读取pattern.dateformat、pattern.envSharedValue和pattern.name的值
 * 并设置到PatternProperties类的对应字段上
 * 在应用的其他地方,你可以通过注入PatternProperties Bean来获取这些配置属性的值
 */
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    private String dateformat;
    private String envSharedValue;
    private String name;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3) UserApplication.java

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

@MapperScan("com.example.user.mapper")
@SpringBootApplication
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}
1
2
3
4
5
6
7
8
9
10
11

# 4) web

  • web/UserController.java
import com.example.user.config.PatternProperties;
import com.example.user.pojo.User;
import com.example.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

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

    @Autowired
    private UserService userService;

    // @Value("${pattern.dateformat}")
    // private String dateformat;

    @Autowired
    private PatternProperties properties;

    @GetMapping("prop")
    public PatternProperties properties(){
        return properties;
    }

    @GetMapping("now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat()));
    }

    /**
     * 路径: /user/110
     *
     * @param id 用户id
     * @return 用户
     */
    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id,
                          @RequestHeader(value = "Truth", required = false) String truth) {
        System.out.println("truth: " + truth);
        return userService.queryById(id);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 5) service

  • service/UserService.java
import com.example.user.mapper.UserMapper;
import com.example.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 6) mapper

  • mapper/UserMapper.java
import com.example.user.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {
    
    @Select("select * from tb_user where id = #{id}")
    User findById(@Param("id") Long id);
}
1
2
3
4
5
6
7
8
9

# 7) pojo

  • pojo/User.java
import lombok.Data;

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}
1
2
3
4
5
6
7
8

# 2、order-service

# 0) pom.xml

<?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>com.example</groupId>
        <artifactId>springcloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>order-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!-- nacos客户端依赖包 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--feign客户端依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--引入HttpClient依赖-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>user-service</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>feign-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <!--引入feign的统一api-->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>feign-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

# 1) resource

  • resources/application.yml
server:
  port: 8088
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/cloud_order?useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice  #设置应用名称,这个名称在微服务架构中通常用于服务发现和负载均衡
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848 # nacos服务地址
#      discovery:
#        namespace: 4d6ce343-9e1b-44df-a90f-2cf2b6b3d177 # dev环境
#        ephemeral: false # 是否是临时实例
mybatis:
  type-aliases-package: com.example.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    com.example: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
#eureka:
#  client:
#    service-url:  # eureka的地址信息
#      defaultZone: http://127.0.0.1:10086/eureka

userservice: #这个类是Nacos提供的一个Ribbon的负载均衡策略实现,它可以和Nacos注册中心更好地配合工作
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  # 负载均衡规则
ribbon:  # 在应用启动时,就会预先创建指定服务的LoadBalancer,而不是在第一次请求时才创建
  eager-load:
    enabled: true # 开启饥饿加载
    clients: # 指定饥饿加载的服务名称
      - userservice
feign:
  httpclient:
    enabled: true # 支持HttpClient的开关
    max-connections: 200 # 最大连接数
    max-connections-per-route: 50 # 单个路径的最大连接数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 2) OrderApplication.java

import com.example.feign.clients.UserClient;
import com.example.feign.config.DefaultFeignConfiguration;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@MapperScan("com.example.order.mapper")
@SpringBootApplication
@EnableFeignClients(clients = UserClient.class,defaultConfiguration = DefaultFeignConfiguration.class)
// 这个注解启用Feign客户端,使得可以通过声明式的方式调用远程服务
// clients属性指定了哪些接口被注册为Feign客户端,defaultConfiguration属性指定了Feign客户端的默认配置类
public class OrderApplication {

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

    /**
     * 创建RestTemplate并注入Spring容器
     * RestTemplate是Spring提供的一个用于发起HTTP请求的同步客户端
     * 给RestTemplate实例添加负载均衡的能力,它会根据服务名称来选择合适的实例
     * 在与Eureka或其他服务发现工具结合使用时,这允许RestTemplate通过逻辑服务名称(而不是具体的URL)来调用服务
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

   @Bean // 创建Ribbon的负载均衡规则, 指定使用随机选择算法
    public IRule randomRule() {
        return new RandomRule();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 3) web

  • web/OrderController.java
import com.example.order.pojo.Order;
import com.example.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
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;

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

   @Autowired
   private OrderService orderService;

    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 4) service

  • service/OrderService.java
import com.example.feign.clients.UserClient;
import com.example.feign.pojo.User;
import com.example.order.mapper.OrderMapper;
import com.example.order.pojo.Order;
//import com.example.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserClient userClient;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.用Feign远程调用
        User user = userClient.findById(order.getUserId());
        // 3.封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }

    /*
    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.利用RestTemplate发起http请求,查询用户
        // 2.1.url路径
        String url = "http://userservice/user/" + order.getUserId();
        // 2.2.框架中使用RestTemplate对象发送HTTP GET请求,将响应体转换成User对象
        User user = restTemplate.getForObject(url, User.class);
        // 3.封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }
     */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 5) mapper

  • mapper/OrderMapper.java
import com.example.order.pojo.Order;
import org.apache.ibatis.annotations.Select;

public interface OrderMapper {

    @Select("select * from tb_order where id = #{id}")
    Order findById(Long id);
}
1
2
3
4
5
6
7
8

# 6) pojo

  • pojo/Order.java
import com.example.feign.pojo.User;
import lombok.Data;
//import com.example.user.pojo.User;

@Data
public class Order {
    private Long id;
    private Long price;
    private String name;
    private Integer num;
    private Long userId;
    private User user;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 3、feign-api

# 0) pom.xml

<?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>com.example</groupId>
        <artifactId>springcloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>feign-api</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>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 1) config

  • config/DefaultFeignConfiguration.java
import feign.Logger;
import org.springframework.context.annotation.Bean;

/**
 * 当你在Feign客户端上应用这个配置类时,Feign会按照BASIC级别来记录日志
 * 这样你就可以看到Feign发送的HTTP请求的方法和URL,以及收到的HTTP响应的状态码和执行时间
 */
public class DefaultFeignConfiguration {
    @Bean
    public Logger.Level logLevel(){
        return Logger.Level.BASIC;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2) clients

  • clients/UserClient.java
import com.example.feign.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * 这个接口的作用是,当你调用findById方法的时候,Feign会在网络上发起一个到"userservice"服务的HTTP请求
 * 请求路径是"/user/"加上你传入的id值,然后等待并处理响应
 */

@FeignClient(value = "userservice")  // 注解这是一个Feign客户端,"userservice"是请求服务名
public interface UserClient {

    @GetMapping("/user/{id}")  // 定义HTTP请求是一个GET请求,请求的路径是"/user/{id}"
    User findById(@PathVariable("id") Long id);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 3) pojo

  • pojo/User.java
import lombok.Data;

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}
1
2
3
4
5
6
7
8

# 4、gateway

# 0) pom.xml

<?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>com.example</groupId>
        <artifactId>springcloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>gateway</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>
        <!--网关gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 1) resource

  • resources/application.yml
server:
  port: 10010
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848 # nacos地址
    gateway:
      routes:
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
      default-filters:
        - AddRequestHeader=Truth,Itcast is freaking awesome!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 2) gateway

  • gateway/GatewayApplication.java
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);
    }
}
1
2
3
4
5
6
7
8
9
  • gateway/AuthorizeFilter.java
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 这段代码是Spring Cloud Gateway中的一个全局过滤器,用于对所有经过的请求进行授权验证
 * 全局过滤器是在所有路由之前执行
 */
// @Order(-1)  //指定过滤器的执行顺序,数字越小,优先级越高,越早执行
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.获取参数中的 authorization 参数
        String auth = params.getFirst("authorization");
        // 3.判断参数值是否等于 admin
        if ("admin".equals(auth)) {
            // 4.是,放行
            return chain.filter(exchange);
        }
        // 5.否,拦截
        // 5.1.设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2.拦截请求
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return -1;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
上次更新: 2024/6/17 19:12:09
08.SpringBoot案例
10.Dubbo

← 08.SpringBoot案例 10.Dubbo→

最近更新
01
300.整体设计
06-10
02
06.LangGraph
06-09
03
202.AI销售智能体
06-07
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式