Spring cloud:服务的注册与发现(Eureka)
1、Spring cloud简介
Spring cloud是Spring旗下的项目之一,是一系列框架的有序集合,它将现阶段非常流行的技术整合到一起实现了配置管理、服务发现、智能路由、负载均衡、熔断器、控制总线等等功能。它主要涉及的组件包括:Eureka(注册中心),Zuul(服务网关),Ribbon(负载均衡),Feign(服务调用),Hystrix(熔断器)。通俗的讲,Spring cloud就是用于构建微服务开发和治理的框架集合,而不是一个具体的框架。
2、Eureka
Eureka是Netflix开发的服务发现框架,本身是基于REST的服务,在微服务中,Eureka负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是将需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你,同时,服务提供方与Eureka之间通过“心跳”机制进行监控,当某个服务提供方出现问题,Eureka会把它从服务列表中剔除,这样就实现了服务的自动注册、发现和监控。Eureka原理如图。
Eureka就是服务注册中心,也可以是一个集群,对外暴露自己的地址;
服务提供者(ApplicationService):启动后向Eureka注册自己的信息(地址,提供的服务)。
消费者(ApplicationClient):向Eureka订阅服务,Eureka会把对应的服务的所有提供者的地址列表发送给消费者,并且定期更新。
心跳(renew):提供者定期通过Http方式向Eureka刷新自己的状态。
3、搭建Eureka微服务工程
1、创建父工程
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.piscest</groupId>
<artifactId>springcloudDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<mapper.starter.version>2.1.5</mapper.starter.version>
<mysql.version>5.1.46</mysql.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>
<!-- 通用Mapper启动器 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>${mapper.starter.version}</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、创建子工程(服务提供者user-service)
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>springcloudDemo</artifactId>
<groupId>com.piscest</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>
<!-- 通用Mapper启动器 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
在user-service\src\main\resources 下创建application.yml文件
server:
port: 10001
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
username: root
password: root
mybatis:
type-aliases-package: com.piscest.user.pojo
创建启动类
package com.piscest.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan("com.piscest.user.mapper")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
创建实体类
package com.piscest.user.pojo;
import lombok.Data;
import javax.persistence.*;
@Data
@Table(name = "tb_user")
public class User {
//id
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//用户名
@Column(name = "username")
private String userName;
//密码
@Column(name = "userpass")
private String userPass;
//年龄
@Column(name = "age")
private Integer age;
}
UserMapper
package com.piscest.user.mapper;
import com.piscest.user.pojo.User;
import tk.mybatis.mapper.common.Mapper;
public interface UserMapper extends Mapper<User> {
}
service
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id){
return this.userMapper.selectByPrimaryKey(id);
}
}
controller 对外提供REST风格Web服务,根据id查询用户,注解@Controller和@ResponseBody可以用@RestController代替,@RestController是@Controller和@ResponseBody的结合体,@Controller类中的方法可以直接通过返回String跳转到jsp、html等页面,加上@ResponseBody可以返回实体类对象,@RestController只能返回String、Object、Json等实体对象,不能跳转模板页面。
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
@ResponseBody
public User queryById(@PathVariable Long id){
return userService.queryById(id);
}
}
完整的项目结构
启动测试,访问localhost:10001/user/3
3.创建子工程(服务发现者consumer-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>springcloudDemo</artifactId>
<groupId>com.piscest</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consumer-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
创建启动类和配置文件
启动类
@SpringBootApplication
@EnableDiscoveryClient //开启Eureka客户端发现功能
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
配置文件
spring:
application:
name: consumer-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10000/eureka
创建实体类
@Data
public class User {
//id
private Long id;
//用户名
private String userName;
//密码
private String userPass;
//年龄
private Integer age;
}
controller
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/{id}")
public User queryById(@PathVariable Long id){
// String url = "http://localhost:10001/user/"+id;
List<ServiceInstance> serviceInstances= discoveryClient.getInstances("user-service");
ServiceInstance serviceInstance = serviceInstances.get(0);
String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/user/"+id;
return restTemplate.getForObject(url,User.class);
}
}
此时,Eureka注册中心还未创建,但是可以通过String url = “http://localhost:10001/user/”+id;直接访问到user-service
项目结构
4.创建Eureka注册中心
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>springcloudDemo</artifactId>
<groupId>com.piscest</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Eureka</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
创建启动类和配置文件
@SpringBootApplication
@EnableEurekaServer //开启Eureka服务
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
server:
port: 10000
spring:
application:
name: eureka-server
eureka:
client:
service-url:
# eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址
defaultZone: http://127.0.0.1:10000/eureka
# 不注册自己
register-with-eureka: false
# 不拉取服务
fetch-registry: false
Eureka项目结构
启动Eureka,并同时启动user-service和consumer-service,访问localhost:10000,可以看到user-service和consumer-service已经注册到Eureka