微服务:
大型系统架构中,会拆分多个子系统。简单来说,这些子系统有两个功能:提供接口、调用接口,在微服务架构中,将每一个这样的子系统称为一个“微服务”;
每一个服务会部署多个实例(就是多台机器,且会动态扩容,IP不固定);
这种情况下,需要使用eureka进行服务管理。服务ID/名称 是唯一的标识, 接口调用前,根据ID在注册中心找到对应的实例信息(ip端口等),然后再直调服务。
一、spring cloud服务注册中心
1、首先是pom文件,以下都是是使用spring cloud必须配置的内容。
<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>
<!-- spring boot 封装spring
starter封装、自动配置autoconfiguration
-->
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Dalston.SR1</version>
<relativePath />
</parent>
<groupId>com.dongnaoedu.springcloud</groupId><!-- 可以是自己的名称 -->
<artifactId>lession-1-eureka</artifactId><!-- 可以自定义id -->
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring-boot-starter-web web项目,集成容器tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring-boot-starter-actuator 管理工具/web 查看堆栈,动态刷新配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- cloud eureka组件 注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、配置bootstrap.yml
# 比application context先加载
# 应用名称 项目运行后的名称
spring:
application:
name: eureka-server
3、application.yml
# 上下文初始化加载
info:
name: Eureka server
contact: 动脑科技VIP
spring:
profiles:
active: dev
---
spring:
profiles: dev
server:
port: 8761
eureka:
client:
# 是否注册到eurekaserver
registerWithEureka: true
# 是否拉取信息
fetchRegistry: false
# eureka server地址
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/
server:
waitTimeInMsWhenSyncEmpty: 0
# false 关闭自我保护,不管如何都要剔除心跳检测异常的服务
enableSelfPreservation: true
# updatePeerEurekaNodes执行间隔
peerEurekaNodesUpdateIntervalMs: 10000000
instance:
hostname: eureka1
---
spring:
profiles: eureka1
server:
port: 8761
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/,http://eureka3:8763/eureka/
server:
waitTimeInMsWhenSyncEmpty: 0
instance:
hostname: eureka1
metadataMap:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
---
spring:
profiles: eureka2
server:
port: 8762
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/,http://eureka3:8763/eureka/
server:
waitTimeInMsWhenSyncEmpty: 0
instance:
hostname: eureka2
metadataMap:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
---
spring:
profiles: eureka3
server:
port: 8763
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/,http://eureka3:8763/eureka/
server:
waitTimeInMsWhenSyncEmpty: 0
instance:
hostname: eureka3
metadataMap:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
4、启动类
服务启动类必须有两个注解
@SpringBootApplication//spring cloud是基于springboot的
@EnableEurekaServer//开启EurekaServer
package com.dongnaoedu.springcloud;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer//开启EurekaServer
public class EurekaApp {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaApp.class).web(true).run(args);
}
}
5、启动查看信息
启动后进入:http://localhost:8761/ 可查看项目信息
信息解释:
二、服务提供者
1、pom文件
<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>
<!-- spring boot 封装spring
starter封装、自动配置autoconfiguration
-->
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Dalston.SR1</version>
<relativePath />
</parent>
<groupId>com.dongnaoedu.springcloud</groupId>
<artifactId>lession-1-sms-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring-boot-starter-web web项目,集成容器tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring-boot-starter-actuator 管理工具/web 查看堆栈,动态刷新配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- cloud eureka组件 客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、bootstrap.yml
# 比application先加载
spring:
application:
name: lession-1-sms-interface
3、application.yml
# 上下文初始化加载
info:
name: lession-1-sms-interface
#端口
server:
port: 9002
# 配置eureka
eureka:
client:
registerWithEureka: true
fetchRegistry: true
# eureka server地址
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/
instance:
# 心跳间隔
# properties中配置:eureka.instance.leaseRenewalIntervalInSeconds
leaseRenewalIntervalInSeconds: 30
# 这个配置会被spring.application.instance_id覆盖(默认 hostname,appnane,port)
# metadataMap:
# instanceId: ${spring.application.name}:${spring.cloud.client.hostname}:${server.port}:${random.value}
4、启动类
package com.dongnaoedu.springcloud;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
// 服务提供者 - 短信接口
@SpringBootApplication//springcloud是基于springboot的
@EnableEurekaClient//Eureka客户端,用来获取信息
public class SmsInterfaceApp {
public static void main(String[] args) {
new SpringApplicationBuilder(SmsInterfaceApp.class).web(true).run(args);
}
}
5、control
package com.dongnaoedu.springcloud;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
// spring data rest 技术
@RepositoryRestResource(collectionResourceRel = "sms", path = "sms")
public interface SmsController extends PagingAndSortingRepository<SmsDomain, Long> {
}
6、bean
package com.dongnaoedu.springcloud;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "sms")
public class SmsDomain implements Serializable {
private static final long serialVersionUID = -2485043500570220853L;
@Id
@GeneratedValue
private Long smsId;
@Column
private String phone;
@Column
private String content;
public Long getSmsId() {
return smsId;
}
public void setSmsId(Long smsId) {
this.smsId = smsId;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
三、服务消费者
消费者和提供者的pom文件和application和bootstrap还有启动类的代码都和服务提供者没什么区别,就不在贴出来了,想看的朋友可以下载源码查看。
消费者control:
package com.tony.springcloud;
import java.io.IOException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
@Autowired
DiscoveryClient discoveryClient;// spring cloud 提供的客户端工具
@RequestMapping("test")
public String test() throws IOException{
// 调用服务器之前,通过eureka client 查询服务的实例信息
// 也就是说去看 部署了哪些机器,以及IP 端口等信息
List<ServiceInstance> instances = discoveryClient.getInstances("lession-1-sms-interface");
for (ServiceInstance serviceInstance : instances) {
System.out.println("获取到服务实例:" + serviceInstance.getPort());
}
// ribbon 客户端负载均衡
ServiceInstance serviceInstance = instances.get(0);
// 获取的IP 端口 信息
String host = serviceInstance.getHost();
int port = serviceInstance.getPort();
String result = new RestTemplate().getForObject("http://" + host + ":" + port +"/sms/1", String.class);
return result;
}
}
四、功能操作
分别运行注册中心,服务提供者,服务消费者的启动类,然后用火狐的接口测试工具调用服务提供者的sms接口(http://localhost:9002/sms)保存信息:
然后调用服务消费者的“test”接口就可以访问到服务提供者的接口了:
通过这种方式就可以实现分布式,往深了学,这里还会涉及负载均衡,前后端分离也是用这个形式实现的。