1.项目背景
系统1.0用springboot+hibernate+jpa,整个系统有web端,ipad端和后端。随着系统业务的扩大和微服务的拓展,1.0系统逐渐力不从心。因此,有了另起系统2.0的想法。18年年底开始2.0系统(spring cloud + mybatis)的搭建和开发,于19年3月完成了整个系统的架构和权限认证,IP拦截,以及软干个微服务。但是后来需求猛增,系统1.0的全面重构只能改为逐步重构。但是领导又觉得1.0系统越来越臃肿,而且报表服务,调度服务因为需求紧迫,还存在接口暴露的问题,于是我只能想了个折中的办法,把系统1.0以及一些单独项目纳入到系统2.0中,这样就可以共享2.0的权限认证,IP拦截,并且方便以后扩展微服务,同时又解决了现有几个服务接口暴露的问题。
2.思路
系统1.0和另外几个单独服务都是基于springboot开发的,2.0是基于spring cloud开发的,而spring cloud是spring boot的进阶版,所以把1.0当做一个微服务通过eureka注册到2.0的服务集群中,理论上是可行的。
3.过程
spring cloud比spring boot多了个配置文件applicataion.yml。用来配置eureka,zuul。
(1)给系统1.0新建的applicataion.yml (暂时给系统1.0取名为project)
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:1111/eureka/
server:
port: 8000
spring:
application:
name: project
security:
oauth2:
resource:
id: project
user-info-uri: http://127.0.0.1:8080/security/user
prefer-token-info: false
系统2.0的eureka的application.properties配置如下:
server.port=1111
eureka.instance.hostname=127.0.0.1
spring.cloud.client.ipAddress=127.0.0.1
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
(2)在gateway(通过zuul实现)的application.yml中添加路由转发配置:
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:1111/eureka/
server:
port: 8080
undertow:
accesslog:
dir:
enabled: false
pattern: common
prefix: access_log
suffix: log
max-http-post-size: 0
io-threads: 4
worker-threads: 20
buffer-size: 1024
direct-buffers: true
spring:
application:
name: gateway
zuul:
routes:
security-service:
path: /security/**
sensitiveHeaders:
serviceId: security-service
project:
path: /erp/**
sensitiveHeaders:
serviceId: project
stripPrefix: false
add-proxy-headers: true
retryable: false
ribbon:
ReadTimeout: 50000
ConnectTimeout: 50000
security:
oauth2:
client:
access-token-uri: http://127.0.0.1:8080/security/oauth/token
user-authorization-uri: http://127.0.0.1:8080/security/oauth/authorize
client-id: INTERNAL
resource:
user-info-uri: http://127.0.0.1:8080/security/user
prefer-token-info: false
(3)至此已经有4个服务,分别是eureka,gateway,security-service,project。
gateway,security-service,project通过eureka注册和发现服务,security-service,project通过gateway转发请求。正常流程是:对project的一个请求{{host}}/erp/notificationProfile/sms,请求到达gateway时,gateway会发出
http://127.0.0.1:8080/security/user
请求到security-service,去验证客户token(Oauth2.0的token机制在这里不做说明),就是gateway的yml里配置的
如果验证通过,gateway会把请求转发到project,但是此处有一个坑。zuul转发的时候回默认吃掉一层前缀,{{host}}/erp/notificationProfile/sms经过转发,会变成{{host}}/notificationProfile/sms从而报404的错误。此时project的所有请求都是带了erp前缀的,所以需要添加 stripPrefix: false。而security-service服务并没有添加这个属性,因为security-service服务在设计之初,controller上的mapping就没有security的前缀,所以经过转发,去掉一层security是适用的。
(4)做完这些,再把eureka和Oauth2.0的依赖添加到project的pom.xml。
<!-- Spring Cloud Eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- Spring security oauth2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-data</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
(5)然后再project的启动类添加 @EnableEurekaClient(@SpringBootApplication原先就有),如:
@SpringBootApplication
@EnableEurekaClient
public class LegoApplication {
public static void main(String[] args) {
SpringApplication.run(LegoApplication.class, args);
}
}
(6)关闭project的ip拦截器,token拦截器。使用2.0gateway的ip验证,security的Oauth2.0的token验证
(7)密码验证,此处不能舍弃原1.0的密码验证部分,不然生产环境的所有密码都将失效。所以将2.0的Oauth2.0的密码验证类重写,具体实现方式使用1.0加盐,MD5加密那一套。
至此,全部工作完成,效果截图如下:
首先是eureka控制台
然后随便call一个普通接口