网关
服务治理,服务注册发现,服务调用,熔断。微服务基本模块已经有了,也可以做微服务了。但完成一个复杂的业务,可能需要多个微服务合作来完成,比如下单,需要用户服务,支付服务,地图服务,订单服务。一般是我们对外服务的窗口,进行服务内外隔离。一般微服务都在内网,不做安全验证。
就好像:很多明星,可以独立开演唱会(独立提供服务)。也可以去春晚(微服务群提供服务)。但一台春晚就不能让 观众一个一个调用了。观众要调用,需要检票啥的,检票就类似于网关,进来之后,界面随便看,不会说你 看个小品,还需要再检票。
微服务没有网关,会有下面的问题:
-
客户端请求多个微服务,增加了客户端复杂性,每个微服务都要做用户认证,限流等,避免和多个微服务打交道的复杂性。
-
有跨域问题,不在同一个域。
-
认证复杂,每个服务都要独立认证,服务要求的权限不一致。
-
难以重构。因为微服务被客户端调用着,重构难以实施。
网关是介于客户端(外部调用方比如app,h5)和微服务的中间层。
Zuul是Netflix开源的微服务网关,核心是一系列过滤器。这些过滤器可以完成以下功能。
- 是所有微服务入口,进行分发。
- 身份认证与安全。识别合法的请求,拦截不合法的请求。
- 监控。在入口处监控,更全面。
- 动态路由。动态将请求分发到不同的后端集群。
- 压力测试。可以逐渐增加对后端服务的流量,进行测试。
- 负载均衡。也是用ribbon。
- 限流(望京超市)。比如我每秒只要1000次,10001次就不让访问了。
- 服务熔断
网关和服务的关系:演员和剧场检票人员的关系。
zuul默认集成了:ribbon和hystrix。
启用网关
-
新建项目引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>
-
配置文件
eureka: client: service-url: defaultZone: http://eureka-7901:7901/eureka/ server: port: 8081 spring: application: name: zuul-test
-
启动类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy public class ZuulTestApplication { public static void main(String[] args) { SpringApplication.run(ZuulTestApplication.class, args); } }
-
启动前面配置的eureka、product、consume
打开 http://localhost:7901/
-
测试访问
http://localhost:8081/consumer/alive
网关会将服务名转换成具体服务的ip和端口,实际进行访问
http://localhost:8081/user-provider/alive -
负载均衡
user-consumer
@GetMapping("/alive2")
public String alive2(){
return "Consumer : " + port + " 》》》 "+restService.alive();
}
RestService
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class RestService {
@Autowired
RestTemplate template;
@HystrixCommand(defaultFallback = "back")
public String alive() {
String url = "http://user-provider/alive";
String forObject = template.getForObject(url, String.class);
return forObject;
}
public String back(){
return "back";
}
}
user-provider
@Override
public String alive(){
System.out.println("alive");
int i = count.getAndIncrement();
System.out.println("port:"+ port + "、弟 " + i + " 次调用");
return "Provider : port : " + port;
}
调用结果,默认轮询
再调用一次
在zuul-test项目中修改负载均衡策略为random
consumer:
ribbon:
NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule