Spring-Boot+Eureka服务注册发现中心server+client案列demo

      上一篇,我们用一个不是很生动的例子,讲述了服务注册中心和服务提供者以及服务消费者三者之间的联系,我们知道了,服务注册发现中心不仅提供服务的注册,而且,还会告诉消费者,当前哪些服务实例是可用的,对管理员也就是我们维护服务的人来说,可以知道,哪些hostname主机上的服务是正常的,当然,那些没有在服务中心出现的服务,我们也可以定位到故障点,比如,服务所在的服务器是不是停电了?或者是断网了?亦或者是被频繁的消费而崩掉了? 


本篇,我们不讲理论,来实战演练,不搞太复杂,就搞个Hello World!


spring-cloud 微服务 使用spring-boot来构建项目非常easy,因此...........



一、Eureka Server中心的搭建



(1)先看项目目录树





1.boot全局run启动入口  - - Application.java

2.boot全局配置属性文件 - - application.properties

3.boot的pom依赖xml配置文件 - - pom.xml


另外,boot打包方式为war包,可以扔在tomcat的webapps文件夹下,随tomcat启动而自行解压部署


(2)pom.xml


<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.appleyk</groupId>
	<artifactId>eureka-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>eureka-server</name>
	<description>基于Spring-Boot快速开发模式的服务注册中心</description>

	<!-- 继承官网最新父POM【假设当前项目不再继承其他POM】 -->
	<!-- http://projects.spring.io/spring-boot/#quick-start -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
	</parent>
	
	<!-- 使用Java8,嘗試使用新特新【stream和lambda】 -->
	<properties>
		<java.version>1.8</java.version>
	</properties>
	
	<!-- spring-cloud集中依赖版本管理,版本见官网 http://projects.spring.io/spring-cloud/ -->
	<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
	<dependencies>
		<!-- Starter POMs是可以包含到应用中的一个方便的依赖关系描述符集合 -->
		<!-- 该Starters包含很多你搭建项目, 快速运行所需的依赖, 并提供一致的, 管理的传递依赖集。 -->
		<!-- 大多数的web应用都使用spring-boot-starter-web模块进行快速搭建和运行。 -->
		<!-- spring-boot-starter-web -->
		<!-- 对全栈web开发的支持, 包括Tomcat和 spring-webmvc -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 添加Eureka Server依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>
		<!-- 添加热部署 devtools:监听文件变动 -->
		<!-- 当Java文件改动时,Spring-boo会快速重新启动 -->
		<!-- 最简单的测试,就是随便找一个文件Ctrl+S一下,就可以看到效果 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<!-- optional=true,依赖不会传递 -->
			<!-- 本项目依赖devtools;若依赖本项目的其他项目想要使用devtools,需要重新引入 -->
			<optional>true</optional>
		</dependency>
	</dependencies>
</project>







可以找到本篇我们使用的spring-cloud的依赖版本











(3)Application.java(boot启动入口)


package com.appleyk;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;


/**
 * 启动类继承SpringBootServletInitializer方可正常部署至常规tomcat下,其主要能够起到web.xml的作用
 * @author yukun24@126.com
 * @blob   http://blog.csdn.net/appleyk
 * @date   2018年2月2日-下午3:52:50
 */

//@EnableEurekaServer:表明应用为eureka服务,有可以联合多个服务作为集群,对外提供服务注册以及发现功能
@EnableEurekaServer
@SpringBootApplication
public class Application extends SpringBootServletInitializer{
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}		
}						




(4)application.properties


#SpringApplication将从以下位置加载application.properties文件, 并把它们添加到Spring Environment中:
#1. 当前目录下的一个/config子目录
#2. 当前目录
#3. 一个classpath下的/config包
#4. classpath根路径(root)
#这个列表是按优先级排序的(列表中位置高的将覆盖位置低的) 。
#注:你可以使用YAML('.yml') 文件替代'.properties'

#当前Spring-boot启动时占用的端口号===即服务注册中心的端口号
server.port=8011
#服务注册中心主机名
eureka.instance.hostname=localhost
#禁止eureka服务向自己注册服务
eureka.client.register-with-eureka=false
#服务中心不去获取(fetch)其他服务,本职工作就是维护服务实例,而不是消费服务
eureka.client.fetch-registry=false
#服务中心 取消自我保护机制,剔除已关停的客户端节点(服务)
eureka.server.enable-self-preservation = false
#服务中心访问ur了地址 === 主机名:端口号/eureka
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/


注意一个地方




如果这里不设置false的话,在eureka client中,如果服务挂掉的话,eureka server中心不会剔除无用的服务实例


(5)run一波我们的eureka server



A.


1.





2.





3.







目前为止,我们的server搭建的很顺利,既然是服务注册发现中心,没有服务怎么能行,下面我们继续





二、Eureka Client的搭建(自身既是服务提供者也是使用者)




(1)先看项目目录树






1.hello world接口服务Controller:HelloController.java

2.boot全局run启动入口  - - Application.java

3.boot全局配置属性文件 - - application.properties

4.boot的pom依赖xml配置文件 - - pom.xml



项目打包方式依然是war




(2)pom.xml (基本上和server的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>
  <groupId>com.appleyk</groupId>
  <artifactId>eureka-client</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>client-client</name>
  <description>基于Spring-Boot快速开发模式的Eureka客户端--即是服务提供者又是服务消费者</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
	</parent>
	<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
	<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-eureka</artifactId>
		</dependency>		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
		</dependency>
		<!-- 监控 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
	</dependencies>	
</project>





所谓的监控,就是在boot启动后,可以通过访问../info 或者.../health页面查询当前服务的"健康"状况





(3)Application.java


package com.appleyk;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

//@EnableDiscoveryClient: 客户端启用服务发现功能
@EnableDiscoveryClient
@SpringBootApplication
public class Application extends SpringBootServletInitializer{
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}	
}



(4)application.properties


#SpringApplication将从以下位置加载application.properties文件, 并把它们添加到Spring Environment中:
#1. 当前目录下的一个/config子目录
#2. 当前目录
#3. 一个classpath下的/config包
#4. classpath根路径(root)
#这个列表是按优先级排序的(列表中位置高的将覆盖位置低的) 。
#注:你可以使用YAML('.yml') 文件替代'.properties'

#当前Spring-boot启动时占用的端口号===即服务注册提供者的端口号
server.port=8080
#注册的服务名 service-id
spring.application.name=hello-service
#服务中心访问ur了地址 === 主机名:端口号/eureka
eureka.client.service-url.defaultZone=http://localhost:8011/eureka/


注意一个地方





       这里,把端口设置成了8080,我们知道,8080是tomcat的默认启动端口,这样设置的目的就是,将当前的client打成war包后,交由tomcat容器启动,因为这个server.port会在eureka服务注册中心以hostname:port的形式显示,因此,这个地方需要和实际的tomacat的启动端口保持一致,后面会在linux系统下进行项目打包部署




(5)HelloController.java


package com.appleyk.controller;

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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController//same as @Controller + @ResponseBody
public class HelloController {

	//载入DiscoveryClient实例
	@Autowired
	private DiscoveryClient client;
	
	@RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String index() {
		/**
		 * 根据eureka的发现功能,获取中心注册的服务实例列表
		 */
        List<ServiceInstance> instances = client.getInstances("hello-service");
        for (int i = 0; i < instances.size(); i++) {
            System.err.println("hello,host:" + instances.get(i).getUri() + ",service_id:" + instances.get(i).getServiceId());
        }
        return "Hello World";
    }
}



(6)先在本地(Windows)下启动client,注册服务



1.





2.







3.









4. 打开地址:9VSNYQQSFL96GK6:hello-service:8080



.../info






..../health




5 服务消费(Hello World)








6 client控制台输出(打印)获取(发现)服务这一过程







(7)关掉当前eureka client服务









(8)90s后,eureka server中心,将剔除掉已经挂了的HELLO-SERVICE服务实例


延迟剔除,因此eureka无法实现分布式中的一致性(剔除时间可以配置)






       根据上一篇说的,鱼塘没有鱼可是不行的啊,于是,我们就想到了,部署多套相同的service,以保证消费者消费服务的时候,不会因为服务挂掉而出现不能用的情况发生

        于是,我准备向eureka server注册两个一模一样的服务,但是两个服务部署在不同的系统中,一个部署在本机Windows下以Spring-Boot内置tomcat的方式启动(注册),另一个部署在本机虚拟机中的Linux系统的tomcat容器中,Ok,说干就干





三、Eureka Client部署到Linux下


由于服务都是一样的,项目demo不需要动,直接利用maven命令打包即可



(1)切换到本地eureka-client项目的src文件夹下







(2)在cmd窗口中进行mvn打包(操作看gif,保证本机maven环境已配置)



gif看不清的话,我这里说下步骤,cmd的话就是切换到当前目录下,然后进行 mvn clean package











(3)打好的war包在target文件夹下(下面是rename后的war包)









(4)将war包上传至Linux系统中的tomcat容器中









(5)启动tomcat


1.







2.tomcat自行解压war包






3.修改tomcat8的server.xml







5.设置eureka server的url(之前忘了这一步)


(设置之前,关掉tomcat)

[root@bogon apache-tomcat-8.0.48]# ./bin/shutdown.sh 








保存后,再次启动tomcat,重新加载配置


[root@bogon apache-tomcat-8.0.48]# ./bin/startup.sh 






6.启动后我们发现,在eureka server服务注册中心多了一个服务实例







7.打开服务地址,并消费服务









四、Eureka Client本地启动(再开一个service)


(1)调整端口号和url,区别Linux下的client






(2)启动








(3)服务注册中心查看服务实例列表








好了,现在在服务注册中心就有了两个一模一样的服务实例 -- HELLO-SERVICE, 而且,这两个实例都是可用的,这就意味着,其中任何一个服务挂掉,都不会影响服务消费者的使用,比如,假设端口号8080的服务实例挂掉了,但是8022的服务实例仍然是可用的,我们在linux中模拟一下,消费8022的服务实例









由于消费了hello-service,所以,在本地的spring-boot项目的控制台中,会打印如下内容









同理,我们还可以模拟服务实例挂掉的情形,由于内容重复,本篇到这里就结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值