一、Zuul(API网关)
spring cloud 的结构:
1、请求统一通过API网关(Zuul)来访问内部服务.2、网关接收到请求后,从注册中心(Eureka)获取可用服务
3、由Ribbon进行均衡负载后,分发到后端具体实例
4、微服务之间通过Feign进行通信处理业务
5、Hystrix负责处理服务超时熔断
6、Turbine监控服务间的调用和熔断相关指标
Zuul的作用就是 :拦截所有请求
1.1 新建一个maven项目Service-Zuul
1.2 引入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.itmyedu</groupId>
<artifactId>Service-Zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 引入springboot父类依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath />
<!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- <version>Finchley.RC1</version> -->
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- springcloud依赖 -->
<!--eureka sping cloud 注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!--eureka server sping cloud 注册服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!-- sping cloud ribbon服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!-- sping cloudzuul网关依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!-- spring boot依赖 -->
<!-- spring boot集成 starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--springboot集成starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- springboot集成web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- json依赖必须要引入不然会报错 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.5</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/milestone/</url>
</repository>
<repository>
<id>org.springframework</id>
<url> http://maven.springframework.org/snapshot</url>
</repository>
<repository>
<id>spring-milestone</id>
<name>Spring Maven MILESTONE Repository</name>
<url>http://repo.spring.io/libs-milestone</url>
</repository>
<repository>
<id>spring-release</id>
<name>Spring Maven RELEASE Repository</name>
<url>http://repo.spring.io/libs-release</url>
</repository>
</repositories>
<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>Finchley.RC1</spring-cloud.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<source>${jdk.version}</source><!-- 源代码使用的开发版本 -->
<target>${jdk.version}</target><!-- 需要生成的目标class文件的编译版本 -->
<encode>${project.build.sourceEncoding}</encode>
</configuration>
</plugin>
</plugins>
</build>
</project>
在(二)的基础上增加了zuul的依赖
<!-- sping cloudzuul网关依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
1.3 增加配置文件
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 8769
spring:
application:
name: Service-Zuul
zuul:
routes:
api-a:
path: /api-member/**
service-id: Service-Member
api-b:
path: /api-order/**
service-id: Service-Order
1.4 在MemberController里添加getMemberServiceApi方法和在OrderController添加getOrderMemberServiceApi方法
package com.itmyedu.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* http://localhost:8762/member/getMemberAll
* http://localhost:8762/member/getMemberServiceApi
* http://localhost:8769/api-member/member/getMemberServiceApi
* @author jack
*
*/
@RestController
@RequestMapping("/member")
public class MemberController {
@Value("${server.port}")
private String serverPort;
@RequestMapping("/getMemberAll")
public List<String> getMemberAll(){
List<String> listUser=new ArrayList<String>();
listUser.add("zhangsan");
listUser.add("lisi");
listUser.add("wangwu");
listUser.add(serverPort);
return listUser;
}
@RequestMapping("/getMemberServiceApi")
public String getMemberServiceApi(){
return "this is Member服务工程 ";
}
}
package com.itmyedu.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.itmyedu.service.OrderMemberService;
/**
* http://localhost:8764/Order/getOrderUserAll
* http://localhost:8764/Order/getOrderMemberServiceApi
* http://localhost:8769/api-order/Order/getOrderMemberServiceApi
* @author jack
*
*/
@RestController
@RequestMapping("/Order")
public class OrderController {
@Autowired
private OrderMemberService orderMemberService;
@RequestMapping("/getOrderUserAll")
public List<String> getOrderUserAll(){
System.out.println("Service-Order:===OrderController==订单开始调用会员服务");
return orderMemberService.getOrderUserAll();
}
@RequestMapping("/getOrderMemberServiceApi")
public String getOrderMemberServiceApi(){
return "this is Order服务工程 ";
}
}
1.5启动类
package com.itmyedu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@SpringBootApplication
@EnableEurekaClient
public class ZuulApp {
public static void main(String[] args) {
SpringApplication.run(ZuulApp.class, args);
}
}
注意:@EnableZuulProxy 开启zuul网关,不然会4041.6 启动Eureka-Server ,Service-Member,Service-Order,Service-Zuul
访问--真实路径访问:http://localhost:8762/member/getMemberServiceApi
访问--真实路径访问:http://localhost:8764/Order/getOrderMemberServiceApi
路由访问:http://localhost:8769/api-member/member/getMemberServiceApi
路由访问:http://localhost:8769/api-order/Order/getOrderMemberServiceApi
由此可见路由已经有效果。
二 、使用zuul网关拦截参数
package com.itmyedu;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
public class MyFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(MyFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
public boolean shouldFilter() {
return true;
}
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
Object accessToken = request.getParameter("token");
if (accessToken != null) {
return null;
}
log.warn("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("token is empty");
} catch (Exception e) {
}
return null;
}
}
再次访问:http://localhost:8769/api-order/Order/getOrderMemberServiceApi
访问路径+token参数:http://localhost:8769/api-member/member/getMemberServiceApi?token=11
好像就加了一次成功之后就不用再加了。