什么是API网关?
当我现在建立了很多个服务之后,大家发现,我每次访问都是直接访问consumer的,然后由consumer去访问provider,像现在这种情况,如果我不想访问consumer,就想直接去访问provider,一样也是可以访问的。那么这样的话就会很乱,所以当我的微服务有成百上千个的时候,我希望给所有的服务有一个统一的入口,所有的请求都从这儿进,所有的请求都从这儿出。这样的话我要去做权限控制也会方便很多,现在的话呢我要在每一个上面去做权限控制,这显然不现实,如果能过统一在某个地方进出的话,我就只需要在那个入口处去做就可以了。
那么扮演这个角色的微服务,我们把它叫做服务网关。
服务网关的用法
首先创建一个名为zuul的新的Module作为网关服务并且加入如下依赖:
在application.properties配置文件中配置如下数据:
spring.application.name=zuul
server.port=5000
eureka.client.service-url.defaultZone=http://localhost:1111/eureka
然后在启动类中加入如下注解,开启zuul的代理:
然后就可以启动它了,当它启动成功后,它会他自己注册到eureka上面去,然后eureka上面也有其他服务注册上来的信息,它会在把自己注册成功后拿到其他所有服务的信息,然后自动帮这些服务做一个代理,这样我们就可以通过网关来访问其他的服务了,当它启动成功后网关的端口是5000,后面加其他服务的名字,后面在家方法名即可访问:
这样就可以直接通过网关来访问其他所有的服务了,但是治理直接用服务名字。可能还是会有点麻烦,可以在配置文件中自定义:
如果想定制多个的话,继续在下面写就行了,这个是允许的,而且当定义了fc之后,以前的旧的也还可以用:
那么默认情况下只要这个zuul注册到eureka上面去了之后,所有注册在eureka上面的服务都会被自动的代理,那如果说现在有某些服务,我不想让它代理呢?这个也是允许的,就以这个feign-consumer为例:
这时候再访问feign-consumer就访问不了了:
所有的请求都从zuul这里过,那么我们就可以通过zuul来做权限控制.
首先定义一个过滤器PermissFilter:
@Component
public class PermissFilter extends ZuulFilter {
@Override
public String filterType() {
//过滤之前
return "pre";
}
@Override
public int filterOrder() {
//过滤器的优先级
return 0;
}
@Override
public boolean shouldFilter() {
//是否应该过滤
return true;
}
@Override
public Object run() throws ZuulException {
//核心方法,在这里写核心业务
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest(); //获取到当前的请求对象
String username = request.getParameter("username");
String password = request.getParameter("password");
if (!("zhangsan".equals(username))||!("123".equals(password))){
ctx.setResponseStatusCode(401); //401表示没有认证(登录)
ctx.setResponseBody("请求非法");
ctx.setSendZuulResponse(false); //没登陆就不用进行转发了
ctx.addZuulResponseHeader("content-type","text/html;charset=utf-8");
}
//返回值不影响运行,无所谓
return null;
}
}
然后重启项目,直接访问feign-consumer就访问不了:
传入账号密码登录之后就可以访问了