• SpringCloud


    1、微服务

    微服务 ≠ SpringCloud

    在这里插入图片描述

    更具体点:

    在这里插入图片描述

    平时普通的项目都是单体架构,不利于大型项目开发。

    在这里插入图片描述

    大型项目常常是分布式架构

    在这里插入图片描述

    微服务架构特征:

    在这里插入图片描述

    单体架构、分布式架构、微服务架构特点:

    在这里插入图片描述

    微服务技术对比:

    在这里插入图片描述

    2、入门案例

    还是新建一个 SpringBoot 项目cloud-demo,然后再其下面再建 SpringBoot 项目来代指不同功能模块。

    父项目pom文件主要组成:

    <modules>
    	<module>user-servicemodule>
    	<module>order-servicemodule>
    modules>
    
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.9.RELEASEversion>
        <relativePath/>
    parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <java.version>1.8java.version>
        <spring-cloud.version>Hoxton.SR10spring-cloud.version>
        <mysql.version>5.1.47mysql.version>
        <mybatis.version>2.1.1mybatis.version>
    properties>
    
    <dependencyManagement>
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>${mysql.version}version>
            dependency>
            
            <dependency>
                <groupId>org.mybatis.spring.bootgroupId>
                <artifactId>mybatis-spring-boot-starterartifactId>
                <version>${mybatis.version}version>
            dependency>
    		
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
            dependency>
        dependencies>
    dependencyManagement>
    
    • 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

    这里举例了两个模块:用户模块和订单模块。

    用户模块写了个根据用户id查询用户的功能。
    订单模块写了个根据订单id查询到订单功能,并根据订单上的用户id查询到用户。

    因为订单模块要跨模块去访问用户模块,因此在订单模块的启动类中,创建RestTemplate并注入Spring容器,且配置负载均衡,当访问的用户模块有多个实例,则通过负载均衡可以指定规则

    @Bean
    @LoadBalanced  // 负载均衡注解,比如要访问的用户模块有多个实例,则通过负载均衡可以指定规则,可以是每次随机,也可以是均匀等。
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、Nacos注册中心

    注册中心是用来统一管理各个微服务模块的地址的。 用来管理各个微服务模块之间的访问。

    3.1 基本配置

    下载安装包:
    https://github.com/alibaba/nacos/releases

    windows:
    解压后进入 bin 目录

    进入cmd,执行命令: startup.cmd -m standalone

    父工程添加 nacos 的 管理依赖:

    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-alibaba-dependenciesartifactId>
        <version>2.2.5.RELEASEversion>
        <type>pomtype>
        <scope>importscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    两个子工程都添加 nacos 的客户端依赖:

    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    订单模块 application.yml 配置:

    server:
      port: 8088
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      application: # 订单模块服务名称配置
        name: orderservice
      cloud: # nacos 配置
        nacos:
          server-addr: localhost:8848 # nacos服务地址
    userservice: # 用户模块的服务名称为userservice,这里意思是仅针对此服务多个实例的负载均衡规则。
      ribbon:
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  # 负载均衡规则
    ribbon:
      eager-load:
        enabled: true # 开启饥饿加载:普通加载是在发起请求时才加载配置,会导致第一次请求很慢,开启饥饿加载后会在项目启动后就加载配置,发起请求后的响应就会快一点。
        clients: # 指定饥饿加载的服务名称
          - userservice
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    用户模块 application.yml 配置:

    server:
      port: 8081
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      application: # 用户模块服务名称配置,用于别的模块调用
        name: userservice
      cloud:
        nacos:
            server-addr: localhost:8848
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    用户模块新增实例:

    在这里插入图片描述

    在这里插入图片描述

    配置完后,可以在订单模块获取到用户模块信息:

    在这里插入图片描述

    3.2 服务集群配置

    一般情况下 会将一个服务模块 的多个实例部署在多个不同的地方(机房)!在同一个机房的实例称为一个集群。

    在这里插入图片描述

    修改用户模块的 application.yml 文件,添加如下内容:

    spring:
      cloud:
        nacos:
            server-addr: localhost:8848  # nacos 服务端地址
            discovery:
              cluster-name: SH  # 配置集群名称,也是机房位置,例如:SH,上海
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    然后启动 UserApplication 和 UserApplication 2

    将 cluster-name 改为 HZ 再启动 UserApplication 3

    在 nacos 服务器网站上 http://192.168.31.41:8848/ 查看:

    在这里插入图片描述

    服务详情中:

    在这里插入图片描述
    总结:
    在这里插入图片描述
    订单模块可通过配置自定义选择用户模块的实例:
    在订单模块 application.yml 下也做相似配置:

    spring:
      cloud:
        nacos:
          server-addr: localhost:8848  # nacos 服务端地址
          discovery:
            cluster-name: HZ  # 配置集群名称,也是机房位置,例如:HZ,杭州
    
    # 还需配置负载均衡。否则不起效,配置为优先选择同集群下实例
    userservice: # 仅针对 userservice服务,即订单模块某一实例访问用户模块时,会优先选择与订单模块实例同集群的用户模块实例
      ribbon:
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  # 负载均衡规则,优先选择同集群下的实例,若有多个,随机访问。若同集群下没有则会跨级访问并发出警告。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    3.3 加权负载均衡

    有时我们想让某些实例优先访问,可以配置实例的权重!比如有些实例要更新可以先把它权重调为0,有些性能差的可以调低一点让访问它的次数小一点。

    在 nacos 服务器上查看到一个服务的各个实例权重相同。

    在这里插入图片描述

    通过编辑可以修改权重。

    在这里插入图片描述

    修改过后,订单模块每次访问用户模块优先访问到权重高的实例。

    3.4 环境隔离-命名空间

    在这里插入图片描述

    默认情况下 所有的服务都位于 nacos 默认的 public 空间下。

    在这里插入图片描述

    新建一个 命名空间

    在这里插入图片描述
    默认服务都在 public 命名空间下,dev为空。需要自己在 代码配置文件中 根据命名空间id 指定。
    在这里插入图片描述

    将用户模块 application.yml 文件更改如下:

    spring:
      cloud:
        nacos:
            server-addr: localhost:8848  # nacos 服务端地址
            discovery:
              cluster-name: HZ  # 配置集群名称,也是机房位置,例如:HZ,杭州
              namespace: 3dc09582-5898-4b36-be3c-4eac2b31ef07
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    然后重新启动 在 nacos 服务器查看到 userservice 服务已被添加到 dev 命名空间

    在这里插入图片描述

    这个时候如果 订单模块 再调用 用户模块的话就会报错,因为这两个服务已经不在同一个命名空间内了,由于隔离,无法相互访问。

    在这里插入图片描述

    总结:

    在这里插入图片描述

    3.5 临时实例与非临时实例

    默认采用临时实例:服务定时给 nacos 注册中心发送心跳,若超过一定时间没发,则剔除此服务。

    可以指定服务application.yml配置设定为非临时实例:不采用心跳方式,而是 nacos 注册中心主动去检测服务是否还在。

    spring:
      cloud:
        nacos:
          discovery:
            ephemeral: false # 是否是临时实例
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    3.5 Eureka 与 Nacos 区别

    在这里插入图片描述
    AP强调可用性和可靠性
    CP强调一致性和可靠性

    4、统一配置管理

    考虑一个场景:当一个配置文件需要修改,且这次修改可能与数十个微服务实例都有关系。那么如果每个微服务实例都修改后重启的话太麻烦了。因此我们希望这些个配置可以统一的修改,在一个地方完成改动,并且改动完后不需要重启,这些服务就立马能够生效!为实现它,引入 nacos 统一配置管理。

    在 nacos 服务器可新增配置

    在这里插入图片描述

    在这里插入图片描述

    项目启动读取过程:

    在这里插入图片描述

    4.1 配置步骤

    1、每个服务都导入nacos配置管理依赖

    <dependency>
       <groupId>com.alibaba.cloudgroupId>
       <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    2、在userservice中的resource目录添加一个 bootstrap.yml 文件,这个文件是引导文件,优先级高于 application.yml。

    spring:
      application:
        name: userservice
      profiles:
        active: dev # 这里指的不是命名空间,这里指定的 userservice 和 dev 则启动的实例会在nacos服务器中拿到  userservice-dev.yaml 文件中的配置。
      cloud:
        nacos:
          server-addr: localhost:8848 # nacos地址
          config:
            file-extension: yaml # 文件后缀名
    
    # 这个bootstrap的作用就是找到nacos中的 userservice-dev.yaml 配置文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3、书写接口拿到userservice-dev.yaml中的数据

    方式一:通过@Value拿到配置值

    @Value("${pattern.dateformat}")
    private String dateformat;
    
    @GetMapping("now")
    public String now(){
       return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    使用@Value的这种方式,要想实现热更新,还需在类上加上 @RefreshScope 注解

    在这里插入图片描述

    方式二:通过@ConfigurationProperties

    在这里插入图片描述

    @Autowired
    private PatternProperties properties;
    
    @GetMapping("prop")
    public String properties(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat()));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    两种方式下,修改配置后:

    在这里插入图片描述

    刷新请求页面,立即生效!

    在这里插入图片描述

    总结:

    在这里插入图片描述

    4.2 多环境配置共享

    在nacos服务器中 配置文件 多个实例可以共享:
    新建一个配置 userservice.yaml 这种命名形式意为共享的,每个指定服务名称为userservice的实例都会共享到此配置。
    还有一个创建的配置文件是 userservice-dev.yaml 指代 dev 环境实例配置文件,每个指定服务名称为userservice,且指定环境 profiles.active 为 dev可访问到此配置文件。

    在这里插入图片描述

    然后启动两个userservice实例
    一个指定profile.active 为 dev,即它可以拿到 userservice.yaml 和 userservice-dev.yaml 的值
    一个指定profile.active 为 test(不存在此配置),它只能拿到 userservice.yaml 的值,拿不到 userservice-dev.yaml 的值

    测试如下:
    在这里插入图片描述

    在这里插入图片描述

    userservice 1:既能访问到共享的配置文件 userservice.yaml 的值,也能访问到 userservice-dev.yaml 中的值

    在这里插入图片描述

    userservice 2:只能访问到共享的配置文件 userservice.yaml 的值,不能访问到 userservice-dev.yaml 中的值

    在这里插入图片描述

    最后再说一下优先级问题。如果在本地代码中也设置了与 nacos 服务器中配置相同的属性。则默认会优先执行 nacos 服务器的。

    在这里插入图片描述

    由上图可以看到优先级配置顺序为:
    (1)bootstrap.yml 指定的 服务名-profile.yml
    (2) bootstrap.yml 指定的 服务名.yml
    (3) 本地 application.yml 配置。

    5、Nacos集群搭建

    5.1 集群结构图

    在这里插入图片描述

    5.2 初始化数据库

    在 localhost 下 新建一个 nacos 数据库,然后执行以下sql语句

    CREATE TABLE `config_info` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(255) DEFAULT NULL,
      `content` longtext NOT NULL COMMENT 'content',
      `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      `src_user` text COMMENT 'source user',
      `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
      `app_name` varchar(128) DEFAULT NULL,
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      `c_desc` varchar(256) DEFAULT NULL,
      `c_use` varchar(64) DEFAULT NULL,
      `effect` varchar(64) DEFAULT NULL,
      `type` varchar(64) DEFAULT NULL,
      `c_schema` text,
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
    
    /******************************************/
    /*   数据库全名 = nacos_config   */
    /*   表名称 = config_info_aggr   */
    /******************************************/
    CREATE TABLE `config_info_aggr` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(255) NOT NULL COMMENT 'group_id',
      `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
      `content` longtext NOT NULL COMMENT '内容',
      `gmt_modified` datetime NOT NULL COMMENT '修改时间',
      `app_name` varchar(128) DEFAULT NULL,
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';
    
    
    /******************************************/
    /*   数据库全名 = nacos_config   */
    /*   表名称 = config_info_beta   */
    /******************************************/
    CREATE TABLE `config_info_beta` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(128) NOT NULL COMMENT 'group_id',
      `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
      `content` longtext NOT NULL COMMENT 'content',
      `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
      `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      `src_user` text COMMENT 'source user',
      `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
    
    /******************************************/
    /*   数据库全名 = nacos_config   */
    /*   表名称 = config_info_tag   */
    /******************************************/
    CREATE TABLE `config_info_tag` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(128) NOT NULL COMMENT 'group_id',
      `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
      `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
      `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
      `content` longtext NOT NULL COMMENT 'content',
      `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      `src_user` text COMMENT 'source user',
      `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
    
    /******************************************/
    /*   数据库全名 = nacos_config   */
    /*   表名称 = config_tags_relation   */
    /******************************************/
    CREATE TABLE `config_tags_relation` (
      `id` bigint(20) NOT NULL COMMENT 'id',
      `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
      `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(128) NOT NULL COMMENT 'group_id',
      `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
      `nid` bigint(20) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`nid`),
      UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
      KEY `idx_tenant_id` (`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
    
    /******************************************/
    /*   数据库全名 = nacos_config   */
    /*   表名称 = group_capacity   */
    /******************************************/
    CREATE TABLE `group_capacity` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
      `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
      `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
      `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
      `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
      `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
      `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_group_id` (`group_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
    
    /******************************************/
    /*   数据库全名 = nacos_config   */
    /*   表名称 = his_config_info   */
    /******************************************/
    CREATE TABLE `his_config_info` (
      `id` bigint(64) unsigned NOT NULL,
      `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `data_id` varchar(255) NOT NULL,
      `group_id` varchar(128) NOT NULL,
      `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
      `content` longtext NOT NULL,
      `md5` varchar(32) DEFAULT NULL,
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `src_user` text,
      `src_ip` varchar(50) DEFAULT NULL,
      `op_type` char(10) DEFAULT NULL,
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      PRIMARY KEY (`nid`),
      KEY `idx_gmt_create` (`gmt_create`),
      KEY `idx_gmt_modified` (`gmt_modified`),
      KEY `idx_did` (`data_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
    
    
    /******************************************/
    /*   数据库全名 = nacos_config   */
    /*   表名称 = tenant_capacity   */
    /******************************************/
    CREATE TABLE `tenant_capacity` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
      `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
      `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
      `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
      `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
      `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
      `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_tenant_id` (`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
    
    
    CREATE TABLE `tenant_info` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `kp` varchar(128) NOT NULL COMMENT 'kp',
      `tenant_id` varchar(128) default '' COMMENT 'tenant_id',
      `tenant_name` varchar(128) default '' COMMENT 'tenant_name',
      `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
      `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
      `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
      `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
      KEY `idx_tenant_id` (`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
    
    CREATE TABLE `users` (
    	`username` varchar(50) NOT NULL PRIMARY KEY,
    	`password` varchar(500) NOT NULL,
    	`enabled` boolean NOT NULL
    );
    
    CREATE TABLE `roles` (
    	`username` varchar(50) NOT NULL,
    	`role` varchar(50) NOT NULL,
    	UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
    );
    
    CREATE TABLE `permissions` (
        `role` varchar(50) NOT NULL,
        `resource` varchar(255) NOT NULL,
        `action` varchar(8) NOT NULL,
        UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
    );
    
    INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
    
    INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
    
    • 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
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198

    5.3 基本配置

    在一台电脑上部署三个nacos节点。

    进入nacos 的 conf目录,修改配置文件 cluster.conf.example,重命名为 cluster.conf 然后打开添加如下内容:

    在这里插入图片描述

    192.168.18.110 是我本机的实际地址(通过cmd 输入 ifconfig 查看无线局域网的那个 ipv4)。

    然后修改 application.properties文件,添加数据库配置

    在这里插入图片描述

    然后将nacos 文件夹赋值为3份,重命名为 nacos1 nacos2 nacos3。
    分别修改 三个文件夹中 application.properties文件,修改端口号为 8845 8846 8847
    随后分别进入三个文件夹中的bin 打开cmd 输入 startup.cmd 启动三个 nacos

    然后配置nginx,修改 conf下的 nginx.conf 文件

    在 http {} 中任意位置 增添如下内容:

    upstream nacos-cluster {
        server 127.0.0.1:8845;
        server 127.0.0.1:8846;
        server 127.0.0.1:8847;
    }
    
    server {
        listen     80; // 只要访问80/nacos 就会代理到 127.0.0.1:8845/nacos 或 127.0.0.1:8846/nacos 或 127.0.0.1:8847/nacos
        server_name localhost;
        
        location /nacos {
            proxy_pass http://nacos-cluster;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    配置过后 在nginx 文件夹打开 cmd 然后 start nginx.exe 启动 nginx。

    这些都配置好后,浏览器访问 localhost:80/nacos
    跳转到 nacos 服务器页面!

    在这里插入图片描述

    此时java代码修改的话 只需将连接的nacos 端口号改为 80 即可!

    在这里插入图片描述

    在nacos服务器 添加一个配置:

    在这里插入图片描述

    添加后会发现数据库 config_info 表 多了一条记录,完成了持久化。

    在这里插入图片描述

    总结:

    在这里插入图片描述

    6、Http客户端 Feign

    6.1 Feign的介绍

    上面在介绍跨模块访问时,采用的是注入 RestTemplate 模板的方式。
    RestTemplate 方式调用存在的问题:
    在这里插入图片描述

    • 代码可读性差,编程体验不统一
    • 参数复杂URL难以维护

    Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign
    其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

    6.2 使用Feign

    1、引入依赖。我们这里是订单模块调用用户模块, 因此在订单模块的pom文件下加依赖(哪个模块要跨模块访问就在哪个模块下引入依赖)

    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、在订单模块的启动类添加注解开启Feign的功能:

    @EnableFeignClients
    
    • 1

    3、编写Feign客户端

    订单模块调用用户模块,在订单模块定义一个访问用户模块的接口。使用 @FeignClient 注解,并指定 value值为 userservice,指定访问的是用户模块。

    在这里插入图片描述
    然后在查询接口中注入此客户端,并调用

    在这里插入图片描述

    启动 orderservice 和 3个userservice实例,访问 localhost:8088/order/101,访问15次。会发现每个实例几乎是均匀5次。也就是说Feign自带负载均衡!

    总结:

    在这里插入图片描述

    6.3 Feign自定义配置

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    6.4 Feign性能优化

    在这里插入图片描述

    在这里插入图片描述
    Feign添加HttpClient的支持,在订单模块pom文件引入依赖:

    
    <dependency>
        <groupId>io.github.openfeigngroupId>
        <artifactId>feign-httpclientartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    appliation.yml 配置连接池:

    feign:
      client:
        config:
          default: # 默认影响到全局的服务
            loggerLevel: basic # 日志级别,basic就是基本的请求和响应信息
      httpclient:
        enabled: true # 开启对feign对HttpClient的支持
        max-connections: 200 # 最大连接数
        max-connections-per-route: 50 # 每个路径的最大连接数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6.5 Feign最佳实践

    考虑到这样一个问题:当有很多服务模块都调用 用户服务,那么每一个服务都写一个 UserClient,可见比较冗余。

    因此可采用抽取的方式:将 FeignClient 抽取为独立模块,并且把与 FeignClient 接口有关的 pojo、默认的Feign配置都放到这个模块中,提供给所有消费者使用。

    在这里插入图片描述

    实现步骤:

    在这里插入图片描述

    新建module feign-api

    在这里插入图片描述

    在 order-service 添加feign的统一api

    在这里插入图片描述

    然后使用的FeignClient、pojo类 都是 feign 模块的

    在这里插入图片描述

    在启动类上需要加上引入的 Feign类,这里订单模块引入要访问用户模块的 Feign类,引入过之后就可以在业务层通过注入 feign类,远程调用用户模块。

    在这里插入图片描述

    7、统一网关Gateway

    在这里插入图片描述
    网关的作用:

    • 对用户请求做身份认真、权限校验
    • 将用户请求路由到微服务,并实现负载均衡
    • 对用户请求做限流

    7.1 基本配置

    1、新建一个module 作为网关模块。并增添如下依赖:

    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-gatewayartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、在 application.yml 中增添如下:

    server:
      port: 10010
    spring:
      application:
        name: gateway # 在注册中心中的服务名称
      cloud:
        nacos:
          server-addr: localhost:8848 # nacos地址,连接到注册中心
        gateway:
          routes:
            - id: user-service # 路由标示,必须唯一
              uri: lb://userservice # 路由的目标地址  lb是负载均衡。 根据服务名找到服务,并负载均衡其多个实例
              predicates: # 路由断言,判断请求是否符合规则
                - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合就转发到路由目的地
            - id: order-service
              uri: lb://orderservice
              predicates:
                - Path=/order/**
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、启动后测试:
    orderservice 启动了一个实例
    userservice 启动了三个实例,用来查看负载均衡

    在这里插入图片描述

    然后在网页端测试:

    在这里插入图片描述

    多刷几次,在idea控制台查看,会发现 userservice 三个实例中 接收到的请求数基本相同。

    在这里插入图片描述

    访问流程图:

    在这里插入图片描述

    总结:

    在这里插入图片描述

    7.2 路由断言工厂

    在这里插入图片描述

    PredicateFactory的作用就是读取用户定义的断言条件,然后对请求做出判断。
    Spring提供了11种基本的 Predicate 工厂:

    在这里插入图片描述

    例如设置:

    在这里插入图片描述

    此时再访问的话就会404,因为不满足访问时间在2031年之后

    在这里插入图片描述

    改成Before,即可访问。

    在这里插入图片描述

    7.3 路由的过滤器配置

    7.3.1 GatewayFilter

    在这里插入图片描述

    具体做的处理由路由过滤器工厂GatewayFilterFactory决定。
    Spring 提供了31种不同的路由过滤器工厂。

    例子:
    在这里插入图片描述
    在controller方法中可以将此参数从请求头获取并打印:

    在这里插入图片描述
    然后在网页发请求,只要是userservice服务相关的,都会被在请求头中增加一个Truth参数!

    可以设置为全局的过滤器 default-filters,即所有经过网关的请求都会走这个过滤!

    在这里插入图片描述

    7.3.2 GlobalFilter

    在这里插入图片描述
    比如需要定义很复杂的处理逻辑,这时候GatewayFilter可能就不满足需求,需要手动写代码实现逻辑。
    自己写一个类,实现 GlobalFilter接口。

    对于下面这个场景:

    在这里插入图片描述

    定义全局过滤器实现:

    在这里插入图片描述

    网页中测试:

    在这里插入图片描述

    总结:

    在这里插入图片描述

    7.3.3 过滤器执行顺序

    在这里插入图片描述

    在这里插入图片描述

    7.4 网关跨域问题处理

    在这里插入图片描述

    在 application.yml 文件中配置即可。

    在这里插入图片描述

  • 相关阅读:
    商品API数据在电商中的应用与实现
    如何正确使用:has和:nth-last-child
    javaEE案例,前后端交互,计算机和用户登录
    Springboot服装服装销售管理系统毕业设计-附源码221801
    【软件测试】什么?这是最全的--金融行业测试类型细分,宝藏干G货......
    AVS3中的intra string copy(ISC)
    【数学建模】MATLAB应用实战系列(九十五)-时间序列预测应用案例(附MATLAB代码)
    算法进阶-2sat-cf-1657F
    《工程伦理与学术道德》第二章习题
    供应链管理系统(Java+SSH+MyEclipse+MySQL)
  • 原文地址:https://blog.csdn.net/henulmh/article/details/128176037