最近微服务好像很火的样子,我司是用阿里的dubbo来搭建微服务的,最初感觉好牛叉的样子,但入职一年接触到现在的感觉是 阿里的东西bug太多了,比如我之前给fastjson提交了个非常猎奇的bug(到现在都没有回复,对阿里的好感度已经降到底了)
Netflix的这些东西也是搞微服务用的,大约有这些东西Zuul、Eureka、Ribbon、Hystrix、Feign,花了一个下午整了个简单的demo。
Eureka
服务发现,一般是有个Eureka Server负责Client的注册,其他没啥功能,需要配合其他工具用
Server
pom.xml1
2
3
4
5
6
7
8<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
TestEurekaServerApplication.java
只需加上@EnableEurekaServer
注解1
2
3
4
5
6
7
8
public class TestEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(TestEurekaServerApplication.class, args);
}
}
application.yml
1 | ## 端口 |
启动后打开浏览器是这样的
Service
我们创建一个服务给远端来调用,这个服务是需要注册到eureka的。主要配置
pom.xml
1 | <dependency> |
TestEurekaServiceApplication.java
创建了个url为/hello的controller方法,我们后面要做的是把这个方法暴露给远程客户端去调用
加上@EnableEurekaClient注解就能注册到Eureka了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class TestEurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(TestEurekaServiceApplication.class, args);
}
}
class RemoteHelloController {
//Eureka会自动注入注册的所有Client信息,不过并没有啥用处
private DiscoveryClient client;
"hello") (
public String hello() {
long start = System.currentTimeMillis();
ServiceInstance instance = client.getLocalServiceInstance();
// 随机睡眠1000毫秒以内
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
long cost = System.currentTimeMillis() - start;
return "Remote Hello~ " + instance.getHost() + ", " + instance.getServiceId()
+ ", spent " + cost;
}
}
application.yml
1 | eureka: |
Client
得有个客户端去调用注册的服务,这个客户端也是要注册到eureka的,和Service在配置上并没有啥不同
1 |
|
调用Service的方法有很多种,下面一一列出来
Ribbon
1 | <dependency> |
Ribbon是个类似于负载均衡的东西,只需要引入Ribbon的依赖,然后Ribbon就会自己创建个RestTemplate的实例了,这个RestTemplate还比较高端,和普通的不一样
比如配置文件里这样写1
2
3
4## ribbon直接映射注册到eureka的服务
ribbon:
eureka:
enabled: true
然后代码里这样写1
restTemplate.getForEntity("http://test-service/hello", String.class).getBody();
调用的就是http://localhost:10002/hello了
以下是稍微完整的栗子
1 |
|
如图:
Zuul
只要引入Zuul依赖,就会自动创建直接可以调用远程服务的mapping path
1 | <dependency> |
启动日志里会出现如下内容1
2016-02-21 15:41:02.741 INFO 13460 --- [pool-5-thread-1] o.s.c.n.zuul.web.ZuulHandlerMapping : Mapped URL path [/test-service/**] onto handler of type [class org.springframework.cloud.netflix.zuul.web.ZuulController]
然后打开这个url
可以自定义这个mapping path
1 | zuul: |
Zuul还可以当动态路由和反向代理来用,就不多讲了
Feign
这个好像才有点远程调用的意思了,可以直接把接口映射到某个controller方法上面去,然后调用这个接口就相当于调用远程controller的方法了
1 | "test-service") ( |
可以直接注入这个RemoteHelloService了1
2
3
4
5
6
7
RemoteHelloService remoteHelloService;
"remoteHello") (
public String remoteHello() {
return remoteHelloService.remoteHello();
}
如图
Hystrix
服务调用出错或者超时的时候可以用这个来解决,还记得上面Service里的hello方法我加了不到一秒的休眠么?
这里直接注入上面Feign的的RemoteHelloService,设置了500毫秒的超时时间,当超时的时候就fallback,去执行timeout方法
1 |
|
如图是超时的情况
注:更多Hystrix属性见这里
Hystrix还有个dashboard,看上去很不错,这里就不介绍啦
有关Spring Cloud更多内容请看官方文档啦(很多东西文档里都没有。。)