logo头像

分享技术,品味人生

微服务-项目搭建

Day01- 微服务治理

本章小结:

  1. 项目环境搭建
    1. IDEA 2021.2旗舰版安装破解
    2. IDEA本地优化(设置代码提示快捷键、忽略大小写提醒强制要求、MAVEN阿里仓+本地仓配置、yaml插件、控制台高亮插件、多服务异端口启动)
    3. Mysql for linux安装(来源HDP安装日志,因项目需要所以前置)
    4. SpringBoot父子工程搭建过程(还需要强化springboot基础)
  2. 微服务の跨服务远程调用及springEureka注册中心的使用
    1. 远程调用基础,引入Spring.RestTemplate,硬编码(真实URL)
    2. EurekaBoot搭建,自身、业务Boot项目注册
    3. 基于Eureka的远程调用(逻辑服务地址)、轮询和随机策略的切换、策略的全局和单个区别、简单介绍并使用饥饿加载方式
  3. 微服务の阿里Nacos注册中心/数据中心使用(完全替换Eureka)
    1. Nacos单机安装、启动和端口设置
    2. Nacos程序植入方式
    3. Nacos限定区域随机策略、跨区服务报警案例
    4. 权重设置、平滑升级准备
    5. 命名空间的隔离,区别生产、测试,这是数据中心的基础
  4. Nacos与Eureka的区别
    1. 服务提供者区别临时和非临时实例,非临时宕机不删除、定期==主动检测==,临时实例30秒主动告知、异常则删除
    2. 服务消费者定期与nacos通讯缓存服务列表,如果服务有宕机、则nacos==主动推动==消息给消费者
    3. Nacos相比Eureka除了支持AP模式,还支持CP模式(如果存在临时实例),保障数据一致性

No.01-项目搭建


[TOC]

1、IDEA开发环境

插件:

  • IDE Eval Reset, 30天反复激活
  • YAML,yaml文件提醒
  • Grep Console,控制台日志高显

从51job下载到了最新的IntelliJ IDEA 2021.2.2 旗舰版

  • 破解通过添加plugin第三方仓库 http://plugins.zhile.io
  • 添加插件 IDE Eval Reset
  • 激活30天(每月循环操作,但可以勾选默认激活省去这个事):
    • Click Help or Get Help -> Eval Reset menu.
    • Click Reset -> Yes button.
    • Restart your IDE.

补充:

  • 修改idea代码提示快捷键为 Alt+/

    image-20211011140722667

  • 修改idea代码提醒忽略大小写

    image-20211011140751333

  • 添加yaml插件,方便application.yml文件编写

image-20211011140837231

  • 修正maven为alibaba源+本地仓加速
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <mirrors>
      <mirror>
        <!--This sends everything else to /public -->
        <id>nexus-aliyun</id>
        <mirrorOf>*</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>
  </mirrors>
  <localRepository>d:\repository</localRepository> 
      <servers>  
        <server>  
             <id>deploymentRepo</id>  
             <username>admin</username>  
             <password>linzhihui</password>  
           </server>  
       	<server>  
             <id>snapshots</id>  
             <username>admin</username>  
             <password>linzhihui</password>  
       </server>
    </servers>	
</settings>

image-20211011141004639

  • 更改主题为白色经典,方便查看

    image-20211012193438008

  • 添加控制台高亮插件 Grep Console

image-20211012193501269

2、Mysql Server Install

用之前大数据验证的HDP安装包和脚本

  • 安装mysql

    #del mariadb 
    rpm -qa |grep mariadb |xargs yum remove -y
    
    #rz 上传
    mkdir mysql-rpm
    tar -xvf mysql-5.7.18-1.el7.x86_64.rpm-bundle.tar -C mysql-rpm/
    
    #安装
    cd mysql-rpm
    rpm -ivh mysql-community-common-5.7.18-1.el7.x86_64.rpm 
    rpm -ivh mysql-community-libs-5.7.18-1.el7.x86_64.rpm 
    rpm -ivh mysql-community-libs-compat-5.7.18-1.el7.x86_64.rpm 
    rpm -ivh mysql-community-embedded-compat-5.7.18-1.el7.x86_64.rpm 
    rpm -ivh mysql-community-devel-5.7.18-1.el7.x86_64.rpm 
    rpm -ivh mysql-community-client-5.7.18-1.el7.x86_64.rpm 
    rpm -ivh mysql-community-server-5.7.18-1.el7.x86_64.rpm --force --nodeps
    
  • 配置mysql

#修改默认字符集
echo 'character_set_server=utf8' >> /etc/my.cnf
echo "init_connect='SET NAMES utf8' " >> /etc/my.cnf


#初始化数据库
mysqld --initialize
chown -R mysql:mysql /var/lib/mysql
systemctl enable mysqld
systemctl start mysqld

#查询初始化密码
cat /var/log/mysqld.log|grep password

#登录
mysql -uroot -p


#修改初识密码为123456
alter user 'root'@'localhost' identified by '123456';
flush privileges;

#开启远程登录,密码可以不一样
grant all privileges on *.* to root@"%" identified by '123456' with grant option;
flush privileges;

3、导入数据

  • mysql创建utf字符集2个数据库cloud_order和cloud_user

    image-20211011141238363

  • 导入user

/*
 Navicat Premium Data Transfer

 Source Server         : local
 Source Server Type    : MySQL
 Source Server Version : 50622
 Source Host           : localhost:3306
 Source Schema         : heima

 Target Server Type    : MySQL
 Target Server Version : 50622
 File Encoding         : 65001

 Date: 01/04/2021 14:57:18
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

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

-- ----------------------------
-- Records of tb_user
-- ----------------------------
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, '范兵兵', '山东省青岛市');

SET FOREIGN_KEY_CHECKS = 1;
  • 导入order
/*
 Navicat Premium Data Transfer

 Source Server         : local
 Source Server Type    : MySQL
 Source Server Version : 50622
 Source Host           : localhost:3306
 Source Schema         : heima

 Target Server Type    : MySQL
 Target Server Version : 50622
 File Encoding         : 65001

 Date: 01/04/2021 14:57:18
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

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

-- ----------------------------
-- Records of tb_order
-- ----------------------------
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);

SET FOREIGN_KEY_CHECKS = 1;

4、创建工程

4.1、创建父工程

  • 新建maven工程,名称为《cloud-demo》,无默认骨架即可,包名com.iyyxx
  • 删除src文件目录
  • 修改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>

    <groupId>com.iyyxx</groupId>
    <artifactId>cloud-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>user-service</module>
        <module>order-service</module>
    </modules>

    <packaging>pom</packaging>

    <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 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</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>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

4.2、创建user model

父工程中添加model,取名【user-service】,同样不要骨架,artifactID=【user-service】,其他配置如下

  • 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>cloud-demo</artifactId>
            <groupId>com.iyyxx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>user-service</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--mysql-->
            <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>
        </dependencies>
        <build>
            <finalName>app</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
  • resources/application.yml

    server:
      port: 8081
    spring:
      datasource:
        url: jdbc:mysql://192.168.20.164:3306/cloud_user?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
    mybatis:
      type-aliases-package: com.iyyxx.user.pojo
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        com.iyyxx: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    
  • com.iyyxx.user.pojo.User

    package com.iyyxx.user.pojo;
    
    import lombok.Data;
    
    @Data
    public class User {
        private Long id;
        private String username;
        private String address;
    }
    
  • com.iyyxx.user.mapper.UserMapper

    package com.iyyxx.user.mapper;
    
    import com.iyyxx.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);
    }
    
  • com.iyyxx.user.service.UserService

    package com.iyyxx.user.service;
    
    import com.iyyxx.user.mapper.UserMapper;
    import com.iyyxx.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);
        }
    }
    
  • com.iyyxx.user.web.UserController

    package com.iyyxx.user.web;
    
    import com.iyyxx.user.pojo.User;
    import com.iyyxx.user.service.UserService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    
    @Slf4j
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        /**
         * 路径: /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);
        }
    }
    
  • com.iyyxx.user.UserApplication ,SpringBoot在IDEA中方便单独启动,后续部署还要琢磨下!

    package com.iyyxx.user;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.mybatis.spring.annotation.MapperScan;
    
    @MapperScan("com.iyyxx.user.mapper")
    @SpringBootApplication
    public class UserApplication {
        public static void main(String[] args) {
            SpringApplication.run(UserApplication.class, args);
        }
    }
    

4.3、创建order model

父工程中添加model,取名【order-service】,同样不要骨架,artifactID=【order-service】,其他配置如下

  • 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>cloud-demo</artifactId>
            <groupId>com.iyyxx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <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>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
    
            
            <!--比user service多了这个引用,因为订单里有用户id/对象-->
            <dependency>
                <groupId>com.iyyxx</groupId>
                <artifactId>user-service</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>
    
  • resources/application.yml

    server:
      port: 8080	#端口与user不同
    spring:
      datasource:
        url: jdbc:mysql://192.168.20.164:3306/cloud_order?useSSL=false	#数据库不同,虽然在一台机器上
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
    mybatis:
      type-aliases-package: com.iyyxx.order.pojo #这里填成user目录也没报错,照常工作。。。
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        com.iyyxx: debug  #这里如果没填正确,日志出不来。。。
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    
  • com.iyyxx.order.pojo.Order

    package com.iyyxx.order.pojo;
    
    import com.iyyxx.user.pojo.User;
    import lombok.Data;
    
    @Data
    public class Order {
        private Long id;
        private Long price;
        private String name;
        private Integer num;
        private Long userId;
        private User user; //多了user
    }
    
  • com.iyyxx.order.mapper.OrderMapper

    package com.iyyxx.order.mapper;
    
    import com.iyyxx.order.pojo.Order;
    import org.apache.ibatis.annotations.Select;
    
    public interface OrderMapper {
    
        @Select("select * from tb_order where id = #{id}")
        Order findById(Long id);
    }
    
  • com.iyyxx.order.service.OrderService

    package com.iyyxx.order.service;
    
    
    import com.iyyxx.order.mapper.OrderMapper;
    import com.iyyxx.order.pojo.Order;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class OrderService {
    
        @Autowired
        private OrderMapper orderMapper;
    
        public Order queryOrderById(Long orderId) {
            
            Order order = orderMapper.findById(orderId);
            return order;
        }
    }
    
  • com.iyyxx.order.web.OrderController

    package com.iyyxx.order.web;
    
    import com.iyyxx.order.pojo.Order;
    import com.iyyxx.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);
        }
    }
    
  • com.iyyxx.order.OrderApplication

    package com.iyyxx.order;
    
    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.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @MapperScan("com.iyyxx.order.mapper")
    @SpringBootApplication
    //@EnableFeizgnClients(clients = UserClient.class,defaultConfiguration = DefaultFeignConfiguration.class)
    public class OrderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
    }
    

5、测试

因为已经集成到IDEA中,所以在service窗口中可以方便启动、终止、重启、web快速访问,如果没有自动识别,可以手工添加一下spring boot的启动服务

image-20211011143555811

不过,这里面视乎有缓存,必要的时候要关闭工程重新进入才会生效!

1

浏览器效果

image-20211011144050392

image-20211011144059563

Microsoft Edge 的 JsonFormat 还是很哇塞的

image-20211011144216764

6、SpringBoot/IDEA环境多实例

  • service窗口右键, copy configuration

image-20211012100033482

  • 配置端口,也就是application.yml的配置信息

image-20211012100241729

  • 查看效果

image-20211012100254884

image-20211012100314339

No.02- 跨服务远程调用

1、Spring容器加入RestTemplate, Service层进行http访问

  • OrderApplication

    package com.iyyxx.order;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @MapperScan("com.iyyxx.order.mapper")
    @SpringBootApplication
    public class OrderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
    
        /**
         * 创建RestTemplate并注入Spring容器
         */
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
  • OrderService

    package com.iyyxx.order.service;
    
    
    import com.iyyxx.order.mapper.OrderMapper;
    import com.iyyxx.order.pojo.Order;
    import com.iyyxx.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 RestTemplate restTemplate;
    
        public Order queryOrderById(Long orderId) {
            // 1.查询订单
            Order order = orderMapper.findById(orderId);
            // 2.利用RestTemplate发起http请求,查询用户
            // 2.1.url路径
            String url = "http://localhost:8081/user/" + order.getUserId();
            // 2.2.发送http请求,实现远程调用
            User user = restTemplate.getForObject(url, User.class);
            // 3.封装user到Order
            order.setUser(user);
            // 4.返回
            return order;
        }
    }
    
  • 实际效果

    image-20211011152003434

2、Eureka Server搭建

  • 创建eureka model

    就是普通springboot程序,空骨架即可

  • 配置pom, 搭建完记得mvn clean一下

    <?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>cloud-demo</artifactId>
            <groupId>com.iyyxx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>eureka-server</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <!-- eureka server -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    
  • 配置application.yml

    server:
      port: 10086 #eureka服务端口,端口号随意,不冲突即可
    spring:
      application:
        name: eurekaserver  #eureka服务名称
    eureka:
      client:
        service-url:  #eureka地址信息
          defaultZone:  http://localhost:10086/eureka	#自己注册到自己
    
  • 编写springboot入口程序, 编写完毕无报错就直接ctrl+shift+f10启动就直接到service窗口了

    package com.iyyxx.eureka;
    
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaApplication.class, args);
        }
    }
    

3、Eureka注册

3.1、user-service注册

  • user-service的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>cloud-demo</artifactId>
            <groupId>com.iyyxx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>user-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>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
            <!--eureka客户端依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
        </dependencies>
        <build>
            <finalName>app</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
  • user-service的application.yml文件更新

    server:
      port: 8081
    spring:
      datasource:
        url: jdbc:mysql://192.168.20.164:3306/cloud_user?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      application:
        name: userservice  #eureka服务名称
    mybatis:
      type-aliases-package: com.iyyxx.user.pojo
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        com.iyyxx: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    eureka: # eureka的地址信息
      client:
        service-url:
          defaultZone:  http://localhost:10086/eureka
    

3.1、order-service注册

  • order-service的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>cloud-demo</artifactId>
            <groupId>com.iyyxx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <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>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.iyyxx</groupId>
                <artifactId>user-service</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <!--eureka客户端依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
        </dependencies>
        <build>
            <finalName>app</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
  • order-service的application.yml文件更新

    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://192.168.20.164:3306/cloud_order?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      application:
        name: orderservice  #eureka服务名称
    
    mybatis:
      type-aliases-package: com.iyyxx.order.pojo
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        com.iyyxx: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    eureka: # eureka的地址信息
      client:
        service-url:
          defaultZone:  http://localhost:10086/eureka
    

3.3、验证

  • 重启微服务检查eureka注册情况

    image-20211011173913913

4、Eureka发现、负载均衡器配置、饥饿加载

4.1、拉取服务(服务发现、同时默认负载均衡器)

  • 修改url地址为逻辑服务名称

    package com.iyyxx.order.service;
    
    
    import com.iyyxx.order.mapper.OrderMapper;
    import com.iyyxx.order.pojo.Order;
    import com.iyyxx.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 RestTemplate restTemplate;
    
        public Order queryOrderById(Long orderId) {
            Order order = orderMapper.findById(orderId);
            // 修改localhost:8081  为 userservice
            String url = "http://userservice/user/" + order.getUserId();
            User user = restTemplate.getForObject(url, User.class);
            order.setUser(user);
            return order;
        }
    }
    
  • 添加负载均衡的注解

    package com.iyyxx.order;
    
    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.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @MapperScan("com.iyyxx.order.mapper")
    @SpringBootApplication
    public class OrderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
    
        /**
         * 添加LoadBalanced注解
         */
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
    }
    

4.2、负载均衡器-策略设置,全局或单个

  • 全局设置(从本服务触发,所有被调用的服务都统一策略)

    package com.iyyxx.order;
    
    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.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @MapperScan("com.iyyxx.order.mapper")
    @SpringBootApplication
    //@EnableFeizgnClients(clients = UserClient.class,defaultConfiguration = DefaultFeignConfiguration.class)
    public class OrderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
    
        
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
        
        /**
         * 全局设定负债均衡器策略
         */
        @Bean
        public IRule randomRule() {
            return new RandomRule();
        }
    }
    
  • 单个服务设置,指从本服务出发,被本服务调用的那个服务指定策略

    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://192.168.20.164:3306/cloud_order?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      application:
        name: orderservice  
    
    mybatis:
      type-aliases-package: com.iyyxx.order.pojo
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        com.iyyxx: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    eureka: 
      client:
        service-url:
          defaultZone:  http://localhost:10086/eureka
          
    userservice:	# 指定服务的轮训策略
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    

4.3、饥饿加载

  • 程序配置

    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://192.168.20.164:3306/cloud_order?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      application:
        name: orderservice  
    
    mybatis:
      type-aliases-package: com.iyyxx.order.pojo
      configuration:
        map-underscore-to-camel-case: true
    logging:
      level:
        com.iyyxx: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    eureka: 
      client:
        service-url:
          defaultZone:  http://localhost:10086/eureka
    userservice:
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    ribbon:
      eager-load:
        enabled: true	# 饥饿加载开关
        clients:
          - userservice	# 指定服务,多个设置都用 - 分隔开
    
  • 未开启前

    image-20211012110904496

  • 开启后

image-20211012111008392

No.03- 替换Alibaba Nacos注册中心

1、Nacos单机安装启动

  • 下载:官网下载

  • 安装配置

    • win解压即可,可以在conf中修改默认端口8848
    • linux同理,需要提前配好jre
  • 启动

    • 单机启动 startup.cmd -m standalone

image-20211012195701954

2、Nacos程序配置

==注意== 要去掉Eureka配置,一山不容二虎

  • 父pom配置

    <!--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>
    
  • boot项目配置

    • pom依赖

      <!-- nacos客户端依赖 -->
      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      </dependency>
      
    • application·.yml

      spring:
        application:
          name: userservice  #xxx服务名称
        cloud:  # nacos settings
          nacos:
            server-addr: localhost:8848 #nacos服务端口
            discovery:
              cluster-name: HZ #分区存储设置
      

3、Nacos 负载均衡策略配置(单区域随机,宕机可跨并报警)

==注意清理干净eureka配置,包括java版、yaml版的策略,找死了==

  • application.yml

    userservice: # 指定服务
      ribbon:
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #默认在本区内随机分配,如果全部失效则跨区访问并报警
    

    image-20211012195633615

  • IDEA多区域配置 配置好分区存储设置后分批重启多个服务即可

  cloud:  
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: FJ	#FJ, HZ,... ...

image-20211012195744608

4、权重设置(可降低单机负载、做平滑升级!)

权重在0-1之间,常用小数,0代表不服务可用于升级平滑切换

image-20211012201343171

5、权限隔离(如生产、测试隔离)

  • 添加命名空间

image-20211012201743767

image-20211012201748326

  • yml配置

    spring:
      cloud:  # nacos settings
        nacos:
          server-addr: localhost:8848
          discovery:
            cluster-name: FJ
            namespace: c8f73bfe-ffbd-493b-a9fa-8885c947ca40 # dev测试环境
    
  • 重启服务查看nacos并测试

image-20211012201759028

image-20211012201803352

image-20211012201815382

image-20211012201843429

6、永久实例配置(非临时、持久化!及时确认状态、高耗能)

配置一个服务实例为永久实例:

spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # 设置为非临时实例

评论系统未开启,无法评论!