微服务day01-认识微服务与Eureka注册中心

一.什么是微服务?

微服务≠springcloud,是一种经过良好架构设计的分布式解决方案,微服务架构特征

  • 单一职责:微服务拆分力度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
  • 面向服务:微服务对外暴露业务接口
  • 自治:团队独立,技术独立,数据独立,部署独立,每个服务有自己独立的数据库
  • 隔离性强:服务调用做好隔离,容错,降级,避免出现级联问题

单体架构

将业务的所有的功能集成到一个项目中开发,打成一个包部署

优点:

  • 架构简单
  • 部署成本低
  • 适合面向企业内部的小项目

缺点:

  • 耦合度高

分布式架构

根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。

优点:

  • 降低了耦合度
  • 有利于服务的拓展升级

二.springcluod

springcluod是目前全球使用最广泛的微服务框架,集成了各种微服务功能组件,并基于springboot实现了这些组件的自动装配
springcloud与springboot的兼容版本
微服务day01-认识微服务与Eureka注册中心_第1张图片

2.1服务的拆分及远程架构

服务拆分

  • 不同的微服务,不开发重复的功能
  • 微服务数据库独立,不要访问其他微服务的数据库
  • 微服务可以将自己的业务暴露为接口,供其他微服务调用

创建数据库以及执行sql语句的小插曲

  创建数据库时,编码使用utf8mb4(我的mysql版本是8.0.33),而给定的资料中是用5版本的mysql导出的sql脚本,因此直接运行可能有些问题。主要是字符集和排序规则的问题,MySQL 8.0 会自动将会话字符集设置为 utf8mb4,因此不需要再手动设置 SET NAMES utf8mb4;mysql5.0常用的字符集是utf8,因此导出的内容可能也涉及utf8字符集的设置,修改为适合MySQL 8.0的utf8mb4即可;另外,不需要再在表级别上设置utf8mb4字符集以及排序规则,我整理了适合5版本以及8版本两个版本的sql脚本

2.1.1 服务拆分的准备工作

cloud-order数据库 MySQL 5.0版本

-- cloud-order数据库 MySQL 5.0版本
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;

cloud-order数据库 MySQL 8.0版本

-- cloud-order数据库 MySQL 8.0版本
-- 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 utf8mb4 COLLATE utf8mb4_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 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;

运行结果
微服务day01-认识微服务与Eureka注册中心_第2张图片

cloud-user数据库 MySQL 5.0版本

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;

cloud-user数据库 MySQL 8.0版本

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 utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '收件人',
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 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;

运行结果
微服务day01-认识微服务与Eureka注册中心_第3张图片

微服务拆分Demo

1.准备工作

 1.创建2个不同的数据库cloud-order与cloud-user

微服务day01-认识微服务与Eureka注册中心_第4张图片

 2.导入相应的sql文件
 3.导入demo
微服务day01-认识微服务与Eureka注册中心_第5张图片
 4.运行两个服务端程序OrderApplication与UserApplication

2.准备工作运行结果

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

2.1.2 服务拆分

1.远程调用方式分析与案例
用户模块对外暴露接口@GetMapping(“/user/{id}”),只要能够发送HTTP请求即可请求目标地址并获得返回结果
使用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发送请求
	        String url="http://localhost:8081/user/"+order.getUserId();
	        User user=restTemplate.getForObject(url,User.class);
	        order.setUser(user);
	        // 4.返回
	        return order;
	    }
	}

运行结果
微服务day01-认识微服务与Eureka注册中心_第6张图片
2.提供者与消费者
提供者:暴露接口给别人调用
消费者:调用别人的接口
服务A调用服务B,服务B调用服务C,此时服务B既可以是提供者也是消费者。

3.Eureka注册中心原理

使用硬编码服务地址,后期有多个提供服务的人时,会造成问题…

Eureka的2个概念

  • eureka-server服务端,注册中心,记录和管理服务
  • eureka-client客户端,无论是服务的提供者还是消费者,都是eureka的客户端

Eureka的使用流程

  • 只要是eureka-client客户端,无论是服务的提供者还是消费者,在启动时都会被注册到eureka-server注册中心,当游人需要调用服务时,不是直接找服务的提供者,而是找Eureka-server,询问是否有相应的服务,Eureka-server找到之后会直接提供给对方。
    微服务day01-认识微服务与Eureka注册中心_第7张图片
  • 然后使用负载均衡,在这些服务之中选择一个。为了保证不会找到挂掉的服务,Eureka每三十秒发送一次请求,如果有的服务没有响应,就认为该服务已经挂掉,将其从注册中心里边清除;
    微服务day01-认识微服务与Eureka注册中心_第8张图片

4.搭建Eureka服务

  • 1.创建项目,导入依赖spring-cloud-starter-netflix-eureka-server(Eureka服务端依赖)
<dependency>
	<goupId>org.springframework.cloudgoupId>
	<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>

微服务day01-认识微服务与Eureka注册中心_第9张图片
由于在父工程中已经指定了spring-cloud依赖库,所以里边的各种spring-cloud组件都已经被指定,因此子工程中eureka依赖不需要指定版本。
微服务day01-认识微服务与Eureka注册中心_第10张图片

2.启动类添加@EnableEurekaServer

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

3.添加配置信息(**由于eureka本身也是一个微服务,所以在启动时会将自己也注册到eureka上,为了将来eureka集群的使用),需要特别注意设置fetch-registry为false ,否则会报错,因为此时并没有其他服务的信息,所以如果让它拉取会报错, register-with-eureka,fetch-registry默认都为true

server:
  port: 10087 # 服务端口


spring:
  application:
    name: eurekaserver # 服务名称

# eureka服务注册信息
eureka:
  client:
    register-with-eureka: true # 是否注册自己的信息到EurekaServer
    fetch-registry: false # 是否拉取其它服务的信息
    service-url:
      defaultZone: http://127.0.0.1:10087/eureka

运行结果:
微服务day01-认识微服务与Eureka注册中心_第11张图片
注册到eureka的实例(一个服务每注册一份就是一个实例)
在这里插入图片描述

5.服务注册
1.导入依赖

		
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>

2.新增配置,以user-service为例(只需要将服务名称改为对应的服务名称即可),其余同理

spring:
  application:
    name: userservice # user服务名称
# eureka服务注册信息
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10087/eureka

3.运行结果,可以看到已经注册了三个服务实例
微服务day01-认识微服务与Eureka注册中心_第12张图片

6.同一个服务多次启动

这是我们当前IDEA的运行面板:

微服务day01-认识微服务与Eureka注册中心_第13张图片

似乎并不是非常的方便,于是我们将其修改为Run Dashboard面板,点击下图所示的“服务”

微服务day01-认识微服务与Eureka注册中心_第14张图片

添加springboot配置即可,运行结果(适用于2020,2021版本):

微服务day01-认识微服务与Eureka注册中心_第15张图片

右键单击一个服务,以orderservice为例,点击“复制配置”

微服务day01-认识微服务与Eureka注册中心_第16张图片

随后弹出窗口

微服务day01-认识微服务与Eureka注册中心_第17张图片

由于启动同样的服务使用同样的端口会造成冲突,所以重新配置新的服务的端口为8082。

微服务day01-认识微服务与Eureka注册中心_第18张图片

点击应用,启动之,运行结果:

微服务day01-认识微服务与Eureka注册中心_第19张图片

此时,在eureka注册中心中配置了2个orderserivce服务

在这里插入图片描述

7.服务的发现
  比如在orderservice中完成服务拉取,“服务拉取”就是**基于服务名称获取服务列表,然后对服务列表做负载均衡。

  • 修改OrderService代码,修改访问的URL路径,用服务名代替IP,端口号
 String url="http://userservice/user/"+order.getUserId();
  • 在RestTemplate中添加负载均衡注解@LoadBalanced
	@Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

你可能感兴趣的:(springcloud,微服务,eureka,架构,java,spring)