Eureka是springCloud体系中的服务发现与治理组件。是由spring社区最大的赞助者之一netflix公司发布的。背景这么高大上,再来看看他是干嘛的,其实,我相信用完的人都会有这种感觉,从功能上来看, 他就是一dubbo,而且是低配版的dubbo。 他的强大需要依赖于springCloud体系内的其他组件。
关于现在微服务框架的选择,之前在网上也搜索了一番,然后真的被现在技术圈的浮夸风给打败了。
一类人是纯粹的人云亦云,摇旗呐喊型。什么都没用过,百度搜一搜,了解下两个项目的背景,就开始大吹特吹。dubbo几年没维护了,就纯粹是个垃圾,springCloud高大上,spring社区一出手就是行业标杆。其实springCloud是个什么东西, 有些什么功能,根本就不知道。一说起eureka,知道是springCloud体系的, 那就是最牛逼的。真的就是人家老外拉出的一坨屎都是香的。跟着别人的屁股后面学框架学傻了的类型。
另一类人是属于特别自信的类型。眼里只有高大上。各种最新技术,吹得天花乱坠。其实真正做事,也就是个拿来主义。拿着一些最新的webservice框架搭起一个系统那就比别人用dubbo运营一个网站好多年要牛逼。其实,越是新的东西其实往往问题越多,需要大量的小白鼠项目来完善。而这类人,就是最好的小白鼠。
好像有点扯远了。 还是回到我们的主题eureka。服务发现与治理,到底是干嘛的?其实说白了,就两件事:1、让服务提供者将服务统一注册进来,并监控他们的状态。保证新的服务能及时注册进来,坏的服务能被及时剔除出去。2、让服务消费者统一调用提供者的服务。消费者在不需要知道服务的提供者是谁,服务的实现细节是什么的情况下,获取到最优质的服务。下面来个具体的例子体验下eureka是如何工作的。
首先准备了三个springboot的示例工程。既然是springCloud体系的高大上技术,用springboot当然是最好的方式,关于springBoot的部分,后面也会整理一些东西来,这里就不多说了。这三个工程干嘛的?应该看名字就能知道。
Client:服务消费者。代码结构如下
Server:服务提供者。 代码结构如下
Eureka:服务治理中心。代码结构如下
下面分别展示这三个工程。
一、服务治理中心 Eureka:
注册中心需要引入eureka的server包,配置eureka的服务中心地址,最后需要在启动类中加入关键注释 @EnableEurekaServer。 关键代码:
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.ftoul</groupId>
<artifactId>DABootEurake</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>DABootEurake</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.xml
server.port=8888
eureka.instance.hostname=localhost
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
启动类
@SpringBootApplication
@EnableEurekaServer
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}
启动之后,就可以访问eureka的注册中心了。红色部分标识目前没有服务注册。–这是当然的啦。
二、服务提供者 Server
服务提供者需要将服务注册到服务中心,供别人进行调用。这里只是用单机的一个服务来做下演示。实际应用中应该是多个服务由多个提供者来进行提供,消费者调用时由注册中心选取一个”最优质”的提供者来提供服务。
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.ftoul</groupId>
<artifactId>DABootServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>DABootServer</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
TestController.java 具体提供的服务。 从代码中也能看出eureka是基于rest协议提供的服务。
@RestController
@RequestMapping(value="/testServe")
public class TestController {
private final Logger logger = Logger.getLogger(getClass());
@RequestMapping(value="/getUser")
public List<User> getUser(@RequestParam int i){
logger.info("getUser param i= "+i);
List<User> res = new ArrayList<User>();
User user1 = new User();
user1.setUserid("1");
user1.setUserid("第一个用户");
user1.setUserPassword("123456");
User user2 = new User();
user2.setUserid("2");
user2.setUserid("第二个用户");
user2.setUserPassword("1234540");
res.add(user1);
res.add(user2);
return res;
}
}
application.xml 配置注册中心地址以及注册的应用名
eureka.client.serviceUrl.defaultZone=http\://localhost\:8888/eureka/
spring.application.name=DABootServer
#tomcat服务端口号
server.port=1111
Provider.java 启动类。 需要引入关键注释 @EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class Provider {
private static final Logger logger = Logger.getLogger(Provider.class);
public static void main(String[] args) {
SpringApplication.run(Provider.class, args);
logger.info("启动服务端注册服务!");
}
}
将服务端启动之后,再次访问之前的注册中心页面:
框框内表明我们的服务已经成功注册上了。目前既然只是体验,那红色的报警部分,暂时忽略。日后再深究。
三、服务消费者 client
服务注册完了开始调用了。
首先还是最关键的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.ftoul</groupId>
<artifactId>DABootClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>DABootClient</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
其中用到了 hystrix 和 feign 两个springCloud组件。这两个组件其实很强大,其实这也代表eureka比dubbo更好更强大的关键,springCloud体系的力量。具体功能,还是先体会了再去深究。
application.xml
spring.application.name=DABootClient
server.port=3333
eureka.client.serviceUrl.defaultZone=http\://localhost\:8888/eureka/
功能演示部分,先对外暴露了一个测试用的访问接口
TestController.java
@RestController
@RequestMapping(value="/Test")
public class TestController {
@Autowired
private UserService userSerivce;
@RequestMapping(value="/getAllUsers")
@ResponseBody
public Object getAllUsers(@RequestParam int i){
return userSerivce.getUser(i);
}
}
其中调用了一个userService服务。 这个服务就配置为从server段调用
userService.java
@FeignClient("DABootServer")
public interface UserService {
@RequestMapping(value="/testServe/getUser",method=RequestMethod.GET)
public List<User> getUser(@RequestParam(value = "i") int i);
}
最后是启动类 关键注释就会比较多。
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableDiscoveryClient
@EnableFeignClients
public class Consumer {
private static final Logger logger = Logger.getLogger(Consumer.class);
public static void main(String[] args) {
SpringApplication.run(Consumer.class, args);
logger.info("启动服务端注册服务!");
}
}
启动类启动起来后。还是先访问我们的注册中心
可以看到 消费者也已经注册上去了。
然后访问消费者工程对外的测试接口:http://localhost:3333/Test/getAllUsers?i=1
同时,在提供者工程的日志监控中,看到了调用记录
到此,整个体验的流程已经完成了,虽然环境很粗糙,但也可以看到springCloud的牛逼之处。三个工程代码量加一起,也不过几十行。区区几行代码就能构建出一个完整的服务。
体验完了之后,就要开始细细总结了。eureka到底怎么样?要怎样才能用好他?我先立个靶子,有兴趣的多来讨论讨论。
首先是服务选取。我们的演示过于简单,其实没有体现出微服务的关键,eureka服务注册中心显得有点多余,提供者和消费者完全可以直接调用嘛。正式应用中,server服务提供者肯定不止一个机器,要采用分布式的部署。A,B,C 三台机器作为server服务端同时提供同一个服务。这时候eureka的作用就重要起来了。每次消费者申请调用一个userService服务,eureka要决定从三个提供者中选择一个机器来提供这个服务。选谁呢?这里面学问就大了。选机器性能最好的?选提供服务次数最少的?还是选最近请求少的?
其次是资源调控。一个消费者端,往往会需要调用好多个服务。而如果消费者突然太多了,比如双十一上淘宝,这时候服务提供者的性能就会遇到瞬间的瓶颈。当然,这时候增加提供者的服务部署是一种方式,但是,在提供者的处理能力提升之前呢?消费者这时就会需要注册中心优先响应最为关键的服务。如何去识别哪些服务更关键?如何去优先响应关键服务?
微服务架构有微服务的优势,也有他的新的问题。调用方便的同时也会响应的增加系统复杂度。当然,有牛人会说,这么个简单的微服务,那我干嘛要用这种模式呢?另外有一百种技术可以实现这种服务调用。我想说,牛逼你自己做出来一个,那我就服你妥妥的。