让ERP的服务更开放! ——用微服务架构搭建的一套基于EBS的API服务系统

1. 源码下载地址

源码链接: https://github.com/samt007/xy…

这是用Spring Cloud微服务架构搭建的一套基于EBS的API服务系统

2. Introduction介绍

这是一篇传统ERP系统和基于Java的微服务架构有效结合的技术文档。

传统ERP关注的是企业内部的信息化管理。当ERP系统能将其服务发布出去之后(结合微服务架构),就可以很好实现与第三方系统的无缝对接,同时也可以实现扩展ERP本身的功能。
目标是:让ERP的服务更开放!

2.1 它有什么用/h2>

简单来说,就是:

相当于做一个中间服务平台,把ERP的功能做成Web Service与其它系统集成。

下面具体说明它的作用。

1. 如果没有它…

所以,有了它,相当于ERP的API都可以通过这服务平台给开发出去,基本上所有的接口可以完成的业务,都可以通过这套服务平台来完成。

可以实现:

  • 对外服务的统一
  • API服务之间可以实现互相调用,并且实现服务取数和处理的逻辑的统一
  • 代码的统一,提高开发效率。特别是comm代码的部分。
  • 提高与第三方系统对接的稳定性:只需要关注该微服务系统的运行稳定性即可。

3. 有哪些实例/h3>

举个例子:

1) 成品进出条码管理系统:

大概这个需求:
成品入库的时候,直接可以用条码枪扫条码或者二维码就可以入库;销售出库的时候,也可以通过刷成品的条码直接进行出库。JIT管理。

通过这个系统的实现逻辑是:
通过EBS的用户名和密码可以登入条码枪上的APP系统。然后,刷条码的时候,通过该Web Service可以产生对应的事务处理!例如完工入库,处理物料搬运单等。

下面是该系统的一些截图

注意:该功能后台API由该微服务提供,前台是安卓的APP

注意:

1.Spring Cloud模块中,实际上Spring Security并不是单独的一个模块,而是融入到每一个业务微服务模块中! 每个微服务都必须要有token认证才允许访问API,它非常重要! 所以我将它给列到Spring Cloud模块中。

2.图中有些模块目前还没有实现。
目前实现了架构整体,包括以下的服务(下一个章节会具体说明每个模块的用途):

xygerp-ald

xygerp-albc

xygerp-server-eureka

xygerp-server-zuul

注意: 以后会按需添加别的模块。

3 系统开发流程

接下来是一步一步来开发一套这个基于Spring Cloud的微服务系统。

3.1 必须掌握的基础开发技术知识点

开发系统都必须要打好基础。所以,这里列出了开发基于Spring Cloud的微服务系统需要掌握的开发技术。

1)Java语言

必须要熟悉java,否则基本不用看文档了。先打好基础吧!

2)Maven项目管理工具

系统开发的项目都是以maven做项目管理的,所以必须要先安装并掌握maven工具。

3)Oracle数据库+PLSQL+SQL语言

数据库端的开发技术。这里选用Oracle数据库,因为EBS就是基于Oracle数据库的ERP系统。

3.2 需要熟悉的java框架

Java技术发展到现在,已经出现了许多非常优秀的开源框架,我们可以借助这些框架来快速开发系统。

3.2.1 Spring框架技术栈(全家桶)

Spring是目前开源的主流的技术包。
该系统主要用到的技术栈是:Spring boot,Spring Security以及Spring Cloud。

1.Spring Boot

系统基于SpringBoot快速开发。选择目前热度很高的SpringBoot,最大限度地降低配置复杂度,把大量的精力投入到业务开发中来。

2.Spring MVC

利用Spring MVC框架处理所有的url请求,简单易用。

3.Spring Security

Spring security是一个强大的和高度可定制的身份验证和访问控制框架。它是确保基于Spring的应用程序的标准。
这里主要是用Spring Security框架处理Token机制。

4.Spring Cloud

Spring Cloud是一系列框架的有序集合。
它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
注意:本系统目前使用Spring Cloud的2个模块

  • 请求统一通过API 关(Zuul)来访问内部服务.
  • 关接收到请求后,从注册中心(Eureka)获取可用服务

3.2.2 MyBatis

ORM框架选用MyBatis。

主要是考虑到它能够很好支持SQL语句:MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。
另外,还用到了MyBatis的一些提高开发效率的插件,特别是通用Mapper和PageHelper分页插件!

3.2.3 Alibaba druid

DRUID是阿里巴巴开源平台上一个数据库连接池实现。它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况。

3.2.4 Swagger

前端和后端的唯一联系,变成了API接口。

API文档变成了前后端开发人员联系的纽带,变得越来越重要,swagger就是一款让你更好的书写API文档的框架。

3.3 需要准备的软件工具

3.3.1Redis

目前用Redis的主要作用是存取token,以配合实现Spring Security完成api访问的安全机制。

以后可以考虑做缓存或者消息队列等高级功能。

3.3.2Docker

基于Docker的容器化部署。

由于使用了微服务架构后,我们的系统将会由很多子系统构成。
为了达到多个系统之间环境隔离的目的,我们可以将它们部署在多台服务器上,可这样的成本会比较高,而且每台服务器的性能可能都没有充分利用起来。

所以我们很自然地想到了虚拟机,在同一台服务器上运行多个虚拟机,从而实现环境的隔离,每个虚拟机上运行独立的服务。

然而虚拟机的隔离成本依旧很高,因为它需要占用服务器较多的硬件资源和软件资源。
所以,在微服务结构下,要实现服务环境的隔离,Docker是最佳选择。它比虚拟机更加轻量级,占用资源较少,而且能够实现快速部署。

3.3.3 Jenkins

Jenkins自动化构建工具。

当我们采用了微服务架构后,我们会发现这样一个问题。整个系统由许许多多的服务构成,这些服务都需要运行在单独的容器中,那么每次发布的复杂度将非常高。

首先你要搞清楚这些服务之间的依赖关系、启动的先后顺序,然后再将多个子系统挨个编译、打包、发布。这些操作技术难度低,却又容易出错。

那么有什么工具能够帮助我们解决这些问题呢案就是——Jenkins。

它是一款自动化构建的工具,简单的来说,就是我们只需要在它的界面上按一个按钮,就可以实现上述一系列复杂的过程。

3.4 具体开发流程

现在开始手把手来搭建一套这样子的系统。

3.4.1 创建Maven项目的组织结构

先创建一个微服务系统的父级项目:xygerp-api

再在这个项目下面分别创建下面几个子项目:

项目名称 说明
xygerp-ald ald模块,端口:8180。这个是整个微服务API的核心ald模块。这个模块的主要功能是验证用户的登录,为所有的api模块提供统一的token认证。相当于ebs的FND模块。
xygerp-albc albc子模块,端口:8181。这个项目是属于微服务的API模块之一:条码管理系统提供数据以及数据处理的API。主要是为条形码传输系统用。
xygerp-comm comm模块这个项目是所有API项目的核心依赖项目。说白了就是将API微服务架构的所有项目的公用代码可以抽取在这里。
xygerp-basic-support 核心基础支撑模块这个项目是所有API项目的基础数据支撑项目。这里统一归集了所有的Entity!因为对于Entity来说,应该是整个微服务都公用的。
xygerp-server-eureka Spring Cloud的服务与发现的服务中心。端口:8101。这个模块是Spring cloud的最核心的模块了,用来处理各个微服务之间的服务调用的。
xygerp-server-zuul Spring Cloud服务 关。端口:8102。在Spring Cloud架构体系内的所有微服务都通过Zuul来对外提供统一的访问入口,所有需要和微服务架构内部服务进行通讯的请求都走统一 关。

它们的目录结果是这样子的:

而xygerp-comm和xygerp-basic-support只是为各个微服务提供基础代码支撑,所以是jar部署即可。

此外,为了简化各个模块的配置,我们将所有模块的通用依赖放在Project的pom文件中,然后让所有模块作为Project的子模块。
这样子模块就可以从父模块中继承所有的依赖,而不需要自己再配置了。

在父pom中指定子模块

modules标签指定了当前模块的子模块是谁,但是仅在父模块的pom文件中指定子模块还不够,还需要在子模块的pom文件中指定父模块是谁。

需要在子模块中指定父模块

备注:具体代码直接看源码吧。这里只是提及了一些重点设置而已。

所以,到此为止,模块的依赖关系配置完毕!但要注意模块打包的顺序。

由于所有模块都依赖于xygerp-comm模块和xygerp-basic-support模块,因此在构建模块时,首先需要编译、打包、安装xygerp-comm模块和xygerp-basic-support模块,将它打包进本地仓库中,这样上层模块才能引用到。当该模块安装完毕后,再构建上层模块。
否则在构建上层模块的时候会出现找不到xygerp-comm模块中类库的问题。

Tips: 其实,如果是在父级目录直接用mvn package整体打包的话,那打包构建的顺序在父pom中是直接指定了!

2. 微服务架构服务治理部分

xygerp-server-eureka:Spring Cloud服务注册和发现。就是处理服务之间的治理。

xygerp-server-zuul:Spring Cloud的统一API 关服务。

Tips: 这2个项目是为了实现微服务架构而用到的核心服务。所以,它们是相对独立的。不需要依赖父pom。

3.4.3用mvn编译命令打包代码

上面的项目都建立好之后,再添加所有项目都需要用到的依赖(具体代码可以参考我的源码)。

都没问题的话,就可以用mvn命令进行打包项目了:

mvn clean install -Dmaven.test.skip=true -P dev

这里简单解析一下指令:

mvn:Maven的统一指令。

clean install:表示要构建该项目。

-Dmaven.test.skip=true:表示构建的时候要跳过测试模块。

-P dev:表示构建的时候,启用 dev 的Spring boot参数运行系统。

如果一切都OK,那正常的结果如下:

3.5.2 本地测试API服务系统

本地测试环境的服务启动起来了,接着就是进行具体的数据测试。

注意,这里用了Spring Security框架,所以的API请求头都必须携带token信息。否则请求会返回401。

如果测试OK,那说明基本上系统已经成功搭建好了。
下一步就是如何在测试环境或者正式环境部署它,以及如何一键构建项目的问题了。

简单来说,系统的部署是用 docker工具 ,一键部署项目用的是 Jenkins工具。后面将会用专题来说明这2个工具的使用。

3.6 该API微服务系统实现的功能难点

3.6.1 解决数据库Session的环境变量问题,特别是语言环境和用户环境。

关于这个问题,目前我用的办法可能不一定是最优的,如果有别的兄台有更好的解决办法,请留言给我,十分感谢!

熟悉EBS开发的兄台都应该知道,登录ERP之后,我们每次打开Form,系统就会申请一个新的数据库Session,这时候,EBS系统会 自动帮我们初始化该Session的环境变量 :例如基本的语言环境,用户环境,业务实体等等。

这时候,我们在包里面可以直接用FND_GLOBAL.USER_ID之类的函数就可以非常方便获取环境变量的信息。

但是,在Java Web开发里面就不一样了!

在Java访问数据库的理念中,Session的申请是一个极耗资源的动作!所以,大部分连接数据库的Java软件都提出了一个 数据库连接池 的概念(例如DRUID数据库连接池)。简单来说就是session共用!

Session公用就会带来一个并发问题:A用户使用系统,并初始化了该Session的环境变量为A用户;当A用户不用系统的时候,Session会闲置并放回连接池里面等待别的用户使用。

这时候如果B的用户很可能会使用该Session,如果不重新初始化环境变量的话,那B用户使用系统的Session的环境变量还是A用户,就会导致数据的bug!
如何处理该问题是开发该系统碰到的一个难题。

问题解决:

我目前的处理办法是:在Service层,用AOP统一自动监控Service层的这个参数AuthUser user

只要在Service层将参数AuthUser user放在最后,AOP会自动初始化Session的环境变量。(需要注意的是,我这个系统的数据库Transaction在Service层启用!)

另外,语言环境变量,登录ID环境变量等,会一并自动初始化。因为AuthUser会携带该定义!

核心处理代码如下:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2018年3月16日
下一篇 2018年3月16日

相关推荐