Eureka简介
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。
Eureka包含两个组件:Eureka Server和Eureka Client:
- Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
- Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
准备工作
- 第一步:
在数据库whyorder创建表tb_order
在数据库whyuser创建表tb_user
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
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;
INSERT INTO `tb_order` VALUES (101, 1, 'Apple 苹果 iPhone 12 ', 5999, 1);
INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新国标电动车', 2099, 1);
INSERT INTO `tb_order` VALUES (103, 3, '骆驼(CAMEL)休闲运动鞋女', 439, 1);
INSERT INTO `tb_order` VALUES (104, 4, '小米10 双模5G 骁龙865', 3599, 1);
INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 双模5G 视频双防抖', 2999, 1);
INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷静星II ', 5449, 1);
INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人体工学电脑椅子', 799, 1);
INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休闲男鞋', 319, 1);
SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
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;
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;
-
第二步:
快速创建两个springboot项目
一个为privoder-server(服务提供者)
一个为consumer-server(服务消费者)
这里我用的是阿里云的镜像地址
-
第三步:引入相关依赖
<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>
<version>2.2.0</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
- 第三步:
快速创建实体类、Dao层、Service层和Controller
//实体类(两个项目的实体类一样)
//----------订单类----------
@Data
public class Order {
private Long id;
private Long price;
private String name;
private Integer num;
private Long userId;
private User user;
}
//----------用户类----------
@Data
public class User {
private Long id;
private String username;
private String address;
}
//---------------Dao层代码(privider-serve)---------------
@Mapper
public interface UserMapper {
@Select("select * from tb_user where id = #{id}")
User selectById(Long id);
}
//---------------Service层代码(privider-serve)---------------
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryUserById(Long id){
User user = userMapper.selectById(id);
return user;
}
}
//---------------Cintroller(privider-serve)---------------
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/{id}")
@ResponseBody
public User queryUser(@PathVariable("id") Long userId){
User user = userService.queryUserById(userId);
return user;
}
}
//---------------Dao层代码(consumer-serve)---------------
@Mapper
public interface OrderMapper {
@Select("select * from tb_order where id = #{id}")
Order selectById(Long id);
}
//---------------Service层代码(consumer-serve)---------------
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
public Order queryOrderById(Long id){
Order order = orderMapper.selectById(id);
return order;
}
}
//---------------Controller(consumer-serve)---------------
@Controller
@RequestMapping("/order")
public class OerderController {
@Autowired
private OrderService orderService;
@RequestMapping("/{id}")
@ResponseBody
public Object queryOrder(@PathVariable("id") Long orderId){
Order order = orderService.queryOrderById(orderId);
return order;
}
}
- 第四步:配置springboot配置文件
#provider-server配置文件
server:
port: 8081
spring:
datasource:
#参数是关于时区和字符集的
url: jdbc:mysql://127.0.0.1:3306/whyuser?serverTimezone=UTC&useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8
username: root
password: why0417
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
type-aliases-package: com.why.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.why: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
#consumer-server配置文件
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/whyorder?serverTimezone=UTC&useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8
username: root
password: why0417
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
type-aliases-package: com.why.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.why: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
搭建Eureka注册中心
-
第一步:快速创建springboot项目
-
第二步:导入eureka依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 第三步:添加@EnableEurekaServer注解
/*Eureka自动装配*/
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
第四步:配置springboot配置文件
server:
port: 8088
spring:
application:
#eureka的服务名称
name: eurekaserver
eureka:
client:
service-url:
#eureka的地址信息
defaultZone: http://localhost:8088/eureka
启动项目并访问Eureka
服务注册
- 第一步:在服务提供者项目中添加eureka-client依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
- 第二步:在application.yml配置文件中配置eureka地址
spring:
application:
#配置服务名称
name: userservice
eureka:
client:
service-url:
#eureka地址信息
defaultZone: http://localhost:8088/eureka
- 第三步:将服务提供者启动多次来模拟多实例部署
修改端口避免端口冲突-Dserver.port=8082
服务发现
- 第一步:在服务消费者项目中添加eureka-client依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
- 第二步:在application.yml配置文件中配置eureka地址
spring:
application:
#配置服务名称
name: userservice
eureka:
client:
service-url:
#eureka地址信息
defaultZone: http://localhost:8088/eureka
- 第三步:注册RestTemplate(Spring提供的发送http请求的工具)
//写在配置类中(或者启动类,因为@SpringBootApplication是复合注解它包括@SpringBootConfiguration注解)
//注入依赖
@Bean
@LoadBalanced //负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
- 第四步:修改Service层代码
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long id){
Order order = orderMapper.selectById(id);
//远程调用
//String url = "http://localhost:8081/user/"+order.getUserId();
//用服务名代替IP端口
String url = "http://userservice/user/"+order.getUserId();
//发送http请求
User user = restTemplate.getForObject(url, User.class);
order.setUser(user);
return order;
}
}
测试
启动所有服务
注册到eureka的实例
访问order