- 环境
- 开始准备
- 工程结构图
- pom
- 编写代码
- 配置文件
- 配置到这里基本就完成了,具体网关的很多策略这里就不讲了,下面就说一下会遇到的问题
- 问题回顾
- 版本问题
- pom错误引入spring-web的组件进入gateway的模块
- 连接zookeeper超时
- 写在最后
文章开始之前,先介绍一下本文的环境,这里要特别注意zookeeper的版本以及你服务器zookeeper的版本,在maven中要注意依赖的问题,后面会解决
| 产品 | 版本 |
|---|---|
| jdk | 8 |
| maven | 3.8.3 |
| springboot | 2.0.4 |
| springcloud | Fincchley.SR1 |
| gateway | 2.0.0.RELEASE |
| zookeeper | 3.4.12 |
compass-zk
|
|
--------------------------------------------------------------
| |
| |
common gateway
|
|
--------------------------
| |
| |
service task
|
|
service-impl
这是我的大致的目录结构,可以作为参考
pom父pom
8 2.0.4.RELEASE 1.7.32 1.2.6 1.18.20 6.0.9.Final 1.2.76 5.7.12 5.1.45 0.9.1 Finchley.SR1 org.slf4j slf4j-api ${slf4j.version} ch.qos.logback logback-core ${logback.version} ch.qos.logback logback-classic ${logback.version} org.projectlombok lombok true ${lombok.version} org.springframework.boot spring-boot-starter-test test ${spring.boot.version} org.hibernate.validator hibernate-validator ${hibernate.version} org.hibernate hibernate-core org.hibernate hibernate-core 5.5.8.Final com.alibaba fastjson ${fastjson.version} cn.hutool hutool-core ${hutool.version} org.springframework.boot spring-boot-starter-data-jpa ${spring.boot.version} org.hibernate hibernate-core org.springframework.boot spring-boot-starter-data-redis ${spring.boot.version} mysql mysql-connector-java ${mysql.version} io.jsonwebtoken jjwt ${jjwt.version} org.springframework.cloud spring-cloud-starter-zookeeper-discovery org.apache.zookeeper zookeeper org.apache.zookeeper zookeeper 3.4.12 org.slf4j slf4j-log4j12 org.springframework.cloud spring-cloud-context com.google.guava guava 31.0.1-jre org.springframework.cloud spring-cloud-starter-openfeign org.springframework.cloud spring-cloud-dependencies ${spring.cloud.version} pom import
这里注意一下我使用的是springcloud整合zookeeper的整合包,重点是要把其自带的zookeeper排除,如果的zookeeper是3.6.0以上就不需要,否则就下面自定义版本以及jar包
gateway的pom
org.springframework.cloud spring-cloud-starter-gateway 2.0.0.RELEASE
这里有一个坑,springcloudgateway采用的是spring-webflux的非阻塞通信技术,切忌不要在这个模块或者其祖先模块将spring-web引入,会引起冲突
编写代码启动类加@EnableDiscoveryClient注解
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
public class UrlGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(UrlGatewayApplication.class, args);
}
@Bean
public ServerCodecConfigurer serverCodecConfigurer()
{
return new DefaultServerCodecConfigurer();
}
}
配置文件
server:
port: 10002
spring:
application:
name: url-gateway
cloud:
zookeeper:
connect-string: xxx.xxx.xxx.xxx:xxxxx
gateway:
globalcors: # 处理跨域
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods:
- GET
- POST
- PUT
- DELETE
routes:
- id: 唯一标识
uri: lb://服务名称
predicates:
- Path=/服务名称/**
filters:
# 匹配后处理,转发时可以删除第一个/前面的路径
- StripPrefix=1
discovery:
locator:
enabled: true
lower-case-service-id: true
配置到这里基本就完成了,具体网关的很多策略这里就不讲了,下面就说一下会遇到的问题 问题回顾这里对StripPrefix再间能讲解一下 举个例子,假如你的访问请求路径是
xxx.xxx.xxx.xxx:xxxxx/服务名称/aaa/bbb ,转发后的路径为 服务对应的路径/aaa/bbb
其实在前面的步骤中,我已经给了避免踩坑的方法,这里避免cv党,就重新描述一下
版本问题控制台输出
KeeperErrorCode = Unimplemented for /services/url-gateway/d6b445e4-92b5-47ea
这里要注意自己的服务器版本,可能是项目中版本与实际版本不一致导致的,不一定高版本的jar会兼容低版本的服务器
pom错误引入spring-web的组件进入gateway的模块**********************************************************
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. Please remove spring-boot-starter-web dependency.
**********************************************************
2020-07-21 10:12:27.253 WARN 8576 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gatewayControllerEndpoint' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration$GatewayActuatorConfiguration.class]: Unsatisfied dependency expressed through method 'gatewayControllerEndpoint' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'modifyRequestBodyGatewayFilterFactory' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]: Unsatisfied dependency expressed through method 'modifyRequestBodyGatewayFilterFactory' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.http.codec.ServerCodecConfigurer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2020-07-21 10:12:27.253 INFO 8576 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2020-07-21 10:12:27.273 INFO 8576 --- [ main] ConditionevaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-07-21 10:12:27.388 ERROR 8576 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.
2020-07-21 10:12:27.398 WARN 8576 --- [ main] o.s.boot.SpringApplication : Unable to close ApplicationContext
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springApplicationAdminRegistrar' defined in class path resource [org/springframework/boot/autoconfigure/admin/SpringApplicationAdminJmxAutoConfiguration.class]: Unsatisfied dependency expressed through method 'springApplicationAdminRegistrar' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.env.Environment' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:539) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.event.AbstractApplicationEventMulticaster.retrieveApplicationListeners(AbstractApplicationEventMulticaster.java:245) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:197) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:134) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:403) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.availability.AvailabilityChangeEvent.publish(AvailabilityChangeEvent.java:81) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.availability.AvailabilityChangeEvent.publish(AvailabilityChangeEvent.java:67) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.doClose(ServletWebServerApplicationContext.java:167) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:978) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:814) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at online.hupeng.cloud.gateway.GateWayApplication.main(GateWayApplication.java:12) [classes/:na]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.env.Environment' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1716) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1272) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 23 common frames omitted
springcloudgateway采用的是spring-webflux的非阻塞通信技术,切忌不要在这个模块或者其祖先模块将spring-web引入,会引起冲突,解决方案,将父版本web放在对应的模块中,不要全局引入,或者全部采用webflux做项目
连接zookeeper超时这里可能是zookeeper挂掉了,这里切忌集群规模不能是偶数,zookeeper是基于raft协议,奇数个比较好一点,还有就是防火墙,确定对应的端口能够访问,zookeeper是使用ftp协议的,注意一下。
写在最后写代码要仔细,尤其是配置文件,很容易出错



