当前版本:SpringCloud Brixton.SR5,SpringBoot 1.3.7.RELEASE
1.声明
当前内容用于学习和复习当前的Spring Cloud,一个微服务框架,分布式的。当前内容为一个极为简单的demo,这里只涉及到Eureka服务治理中心
,即一个类似Zookeeper的东西
服务注册中心,就是一个列表用于显示可使用的服务的列表,可以注册卸载服务的东西,类似注册表之类的(个人理解:程序安装添加注册表,卸载删除注册表)
2.pom依赖
这里直接创建父模块,然后再这个pom依赖中添加其他的模块(子模块中不需要在pom文件中写内容)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>SpringCloud-Start</groupId>
<artifactId>SpringCloud-Start</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>SpringCloud-Start</name>
<url>http://maven.apache.org</url>
<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>Brixton.SR5</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring cloud 的基本配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- spring boot 的基本配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
3.首先创建服务治理中心(EurekaServer)
配置文件:application.properties
server.port=1111
eureka.instance.hostname=localhost
#不将eureka自己注册到服务治理中心
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#设置当前eureka的服务治理中心的显示地方
eureka.client.serverUrl.defaultZone=http:${eureka.instance.hostname}:${server.port}/eureka/
基本的入口类
@EnableEurekaServer // 开启Eureka服务注册中心
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
上面内容中开启类EurekaServer,服务治理中心,并指定了当前服务治理中心的地址(注册中心的地址)
4.创建服务提供者(向服务治理中心注册服务)
server.port=2000
spring.application.name=hello-eureka
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
入口类
@EnableEurekaClient // 激活当前的Eureka中的DiscoverClient实现
@SpringBootApplication
@RestController
public class EurekaProviderApplication {
@Autowired
DiscoveryClient client;//由于上面的注解@EnableEurekaClient注解,所以这里的client实际上就是一个具有当前程序配置的代理类
private final Logger log = LoggerFactory.getLogger(getClass());
@RequestMapping("/hello")
public String home() {
ServiceInstance instance = client.getLocalServiceInstance();// 就是将自身的服务返回即可(实际上就是构建一个新的匿名对象,然后添加自身的数据即可)
log.info("/hello,host:" + instance.getHost() + ",server_id:" + instance.getServiceId());
log.info("/hello,url:" + instance.getUri() + ",metadata:" + instance.getMetadata());
log.info("/hello,isSecure:" + instance.isSecure());
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
}
通过debug发现当前的server_id实际就是程序的名称,然而当前的DiscoveryClient 中提供了通过server_id方式获取多个ServiceInstance(说明可以注册多个app名称的服务)
5.分析上面的配置
1.spring.application.name
表示向Eureka服务治理中心注册的服务id名称,如果注册多个,则表示有一个服务名称可以有多个地方可以访问
下面将当前的服务提供者复制一份,修改配置为server.port=2001
,然后先启动服务注册中心,然后启动两个服务提供者,此时发现
出现了一个服务两个服务提供者,这就是为什么DiscoveryClient这个接口提供这个方法:public List<ServiceInstance> getInstances(String serviceId);
,通过spring.application.name
可以获取List集合的原因
2.分析DsicoveryClient的默认实现类:EurekaDiscoveryClient
本人通过debug发现实际上类型为EurekaDiscoveryClient
,通过查看源码发现,当前EurekaDiscoveryClient提供了
- EurekaInstanceConfig config 使用了
@EnableDiscoveryClient,就会默认注入当前的服务提供者的配置信息,该信息包括当前配置文件中的信息,还包括地址端口等其他信息
- EurekaClient eurekaClient
实际采用这个访问Eureka的服务治理中心(实际上为一个代理类)
代理类的好处,可以延迟操作的实现,屏蔽不必要的实例(例如这里访问Eureka注册中心,代理的方式更好)
3.分析ServiceInstance
- 当前的SpringCloud将每一个服务提供者都描述为:
SerivceInstance
- 通过发现源码
public interface ServiceInstance {
//获取当前服务实例的注册的服务名称
String getServiceId();
//获取当前服务实例的主机名称
String getHost();
//获取当前服务所在的端口
int getPort();
//当前服务实例是否为https
boolean isSecure();
//获取当前服务实例的访问的url,使用http://ip地址:端口
URI getUri();
//获取元数据信息
Map<String, String> getMetadata();
}
从这里可以发现,一般我们访问一个端口(或者一个http的时候,例如HttpClient),只需要url即可访问,采用post或者get就可以访问这个端口,并返回数据信息(当然当前的SpringCloud就是采用RestTemplate来实现访问的,并获取返回结果)
RestTemplate,就是通过一个url,传递的参数数据,然后就可以发起远程调用(一个非常简单的远程调用),然后获取结果并返回,所以服务实例就是一个可以采用远程调用的东西,只是它将参数转发了到了其他服务提供者那里,有服务提供者进行调用,最后将结果通过RestTemplate返回。
6.总结
1.其实SpringCloud的服务治理中心很好理解,实现方式和Zookeeper基本上差不多,只是它和Spring结合的好而已
2.向服务治理中心注册多个服务,只用将当前的spring.application.name
设置一致,就可以实现一个服务有多个服务提供者,实现了分布式的操作
3.SpringCloud的服务调用就是通过RestTemplate来实现调用的,其实和HttpClient差不多,都是通过url访问,传递参数,最后将结果返回(好像远程调用)
4.通过SpringBoot、Zookeeper、HttpClient、RestTemplate的学习就可以很容易理解当前的SpringCloud的Eureka服务治理中心和远程调用的原理
(说明理解更多的东西,就更容易学习其他的技术)
以上纯属个人见解,如有问题请联本人!