快速启动

快速安装并运行Biz-SIP业务中台,并运行相关的测试案例.

一、安装

1 项目源码下载

  1. 从“https://gitee.com/szhengye/biz-sip”中Clone下载项目源码(master分支)。
  2. 在Eclipse或IDEA中作为Maven项目导入。

2 MySQL安装

  1. 安装MySQL镜像
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=bizsip123456 -d mysql
  1. 建库

执行项目中sql/sample.sql脚本,以建立sip演示库。

3 Redis安装

docker run -p 6379:6379 -d redis:latest redis-server

4 RabbitMQ安装

docker pull rabbitmq
docker run -d --name rabbitmq -e RABBITMQ_DEFAULT_USER=springcloud -e RABBITMQ_DEFAULT_PASS=springcloud -p 15672:15672 -p 5672:5672 rabbitmq:management
# 下载延迟队列插件,并拷贝到容器中相关目录
docker cp rabbitmq_delayed_message_exchange-3.8.0.ez rabbitmq:/plugins
# 进入容器交互终端模式,用"docker ps"命令查询RabbitMQ的容器ID
docker exec -it <容器ID> bash
# 执行命令启用延迟队列插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange

5 Nacos安装(SpringCloud版本)

  1. 下载Nacos镜像
docker pull nacos/nacos-server
  1. 启动Nacos镜像
docker run --env MODE=standalone --name nacos -d -p 8848:8848 nacos/nacos-server
# 登录密码默认nacos/nacos
# standalone 代表单机模式运行,非集群模式
  1. 访问Nacos,默认账号/密码:nacos/nacos,访问地址:http://localhost:8848/nacos/index.html

二、配置

1 sample/sample-app模块相关配置文件

application.yml文件:

spring:
  profiles:
    active: local

application-local.yml文件:

server:
  port: 8888

spring:
  application:
    name: bizsip-integrator

  cloud:
    nacos:
      discovery:
        server-addr: bizsip-nacos:8848
        
  datasource:
    url: jdbc:mysql://bizsip-mysql/sip
    username: root
    password: bizsip123456
    driver-class-name: com.mysql.jdbc.Driver

  redis:
    redisson:
      enable: true
    host: bizsip-redis
    port: 6379
    timeout: 6000
    database: 0
    lettuce:
      pool:
        max-active: 10 # 连接池最大连接数(使用负值表示没有限制),如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
        max-idle: 8   # 连接池中的最大空闲连接 ,默认值也是8
        max-wait: 100 # # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
        min-idle: 2    # 连接池中的最小空闲连接 ,默认值也是0
      shutdown-timeout: 100ms

  rabbitmq:
    virtual-host: /
    host: bizsip-rabbitmq
    port: 5672
    username: springcloud
    password: springcloud
    listener:
      simple:
        concurrency: 5
        max-concurrency: 15
        prefetch: 10

bizsip:
  config-path: /var/bizsip/config
  rabbitmq-log: fail

logging:
  level:
    com.bizmda.bizsip: info

其中:

  • server.port:App服务整合器的微服务端口,建议用8888端口,避免和其它端口相冲突。
  • spring.datasource.*:为数据库相关配置,应连接对应的数据库。
  • spring.redis.*:为Redis相关配置,连接对应的Redis。
  • spring.rabbitmq.*:为RabbitMQ相关配置,连接RabbitMQ中间件。
  • bizsip.config-path:配置成项目下sample/config的实际安装目录。
  • bizsip.rabbitmq-log:交易日志开关,可设置为success、suspend、fail,不设置则为不发送交易日志。
  • logging.level.com.bizmda.bizsip:日志级别,一般设置为info。

2 sample/sample-sink模块相关配置文件

application.yml文件:

spring:
  profiles:
    active: local

application-local.yml文件:

server:
  port: 8001
spring:
  application:
    name: bizsip-sample-sink

  cloud:
    nacos:
      discovery:
        server-addr: bizsip-nacos:8848
  #  以下配置在Istio部署中打开,以不采用NACOS注册中心,而采用etcd注册机制
  #  cloud:
  #    service-registry:
  #      auto-registration:
  #        enabled: false  #禁用注册中心服务

  rabbitmq:
    virtual-host: /
    host: bizsip-rabbitmq
    port: 5672
    username: springcloud
    password: springcloud
    listener:
      simple:
        concurrency: 5
        max-concurrency: 15
        prefetch: 10

bizsip:
  config-path: /var/bizsip/config
  sink-id: long-tcp-netty-sink,hello-sink,echo-sink,simple-xml-sink,velocity-json-sink,velocity-xml-sink,fixed-length-sink,velocity-split-sink,iso-8583-sink,netty-sink,sample1-service-sink,sample17-sink,rabbitmq-sink
  rabbitmq-log: success

long-tcp-netty:
  sink-netty-server-port: 10001
  sink-netty-client-host: localhost
  sink-netty-client-port: 10002


logging:
  level:
    com.bizmda.bizsip: debug

其中:

  • server.port:为sample服务接入模块的RESTful服务端口,建议用8080。
  • spring.rabbitmq.*:为RabbitMQ相关配置,连接RabbitMQ中间件。
  • bizsip.config-path:配置成项目下sample/config的实际安装目录。
  • sink-id:如果在当前模块启动时,需要关联启动的Sink,就需要配置这个参数sink-id参数,可以配置多个,以逗号分隔。
  • long-tcp-netty:配置异步长连接测试用例涉及的,Sink作为Netty服务端时的端口,以及作为Netty客户端时的对方服务端IP地址和端口。
  • logging.level.com.bizmda.bizsip:日志级别,一般设置为info。

3 sample/sample-source模块相关配置文件

application.yml文件:

spring:
  profiles:
    active: local

application-local.yml文件:

server:
  port: 8080

spring:
  application:
    name: bizsip-sample-source

  cloud:
    nacos:
      discovery:
        server-addr: bizsip-nacos:8848
  
bizsip:
  config-path: /var/bizsip/config
  integrator-url: http://bizsip-integrator/api

long-tcp-netty:
  source-netty-client-host: localhost
  source-netty-client-port: 10001
  source-netty-server-port: 10002
  
logging:
  level:
    com.bizmda.bizsip: info

其中:

  • server.port:为sample服务调用模块的微服务端口,建议用8001,不要其它端口相冲突。
  • bizsip.integrator-url:为app服务整合器的服务接口url,原则上不需要修改。
  • bizsip.config-path:配置成项目下sample/config的实际安装目录。
  • long-tcp-netty:配置异步长连接测试用例涉及的,Source作为Netty服务端时的端口,以及作为Netty客户端时的对方服务端IP地址和端口。
  • logging.level.com.bizmda.bizsip:日志级别,一般设置为info。

4 source/netty-source模块相关配置文件

application.yml文件:

spring:
  profiles:
    active: local

application-local.yml文件:

server:
  port: 8090

spring:
  application:
    name: bizsip-netty-source

  cloud:
    nacos:
      discovery:
        server-addr: bizsip-nacos:8848

bizsip:
  config-path: /var/bizsip/config
  integrator-url: http://bizsip-integrator/api
  source-id: source1

netty:
  port: 10020

logging:
  level:
    com.bizmda.bizsip: debug

其中:

  • server.port:为sample服务调用模块的微服务端口,建议用8090,不要其它端口相冲突。
  • bizsip.integrator-url:为App服务整合器的服务接口url,原则上不需要修改。
  • bizsip.config-path:配置成项目下sample/config的实际安装目录。
  • bizsip.source-id:为当前source模块的Source ID。
  • netty.port:Source作为Netty服务端时的端口。
  • logging.level.com.bizmda.bizsip:日志级别,一般设置为info。

三、启动系统

1 启动Sample App模块

运行sample/sampel-app模块下“SampleAppApplication.java”

2 启动Sample Sink模块

运行sample/sample-sink模块下“SampleSinkApplication.java”

3 启动Sample Source模块

运行sample/sample-source模块下“SampleSourceApplication.java”

4 启动Netty TCP Source模块(可选)

运行source/netty-source模块下“NettySourceApplication.java”

四、运行Sample测试案例

1 最简单的App服务

通过Biz-SIP的开放API接口发送请求,由App服务后,直接返回。

1、基于App服务脚本的测试用例:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/script/sample1" -X POST --data '{"accountNo":"62001818","sex":"0","email":"123232@163.com","mobile":"18601872345"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/script/sample1",
  "traceId": "5f007c2ed96749249346f8c7369a2f13",
  "parentTraceId": null,
  "timestamp": 1646564075335,
  "data": {
    "sex": "0",
    "mobile": "18601872345",
    "accountNo": "62001818",
    "email": "123232@163.com"
  }
}

2、基于App服务类的测试用例:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1" -X POST --data '{"accountNo":"62001818","sex":"0","email":"123232@163.com","mobile":"18601872345"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample1",
  "traceId": "1a6dea2296604b088564909569685ab3",
  "parentTraceId": null,
  "timestamp": 1646564101826,
  "data": {
    "sex": "0",
    "mobile": "18601872345",
    "accountNo": "62001818",
    "email": "123232@163.com"
  }
}

2 App服务调用Sink服务

通过Biz-SIP的开放API接口,调用hello-sink服务(用HelloSinkBeanService.java类作为模拟),返回Hello消息。

1、基于App服务脚本的测试用例:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/script/sample2" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/script/sample2",
  "traceId": "3368c94e49bf4838add207b48022d31a",
  "parentTraceId": null,
  "timestamp": 1646564157591,
  "data": {
    "message": "hello!",
    "accountNo": "003"
  }
}

2、基于App服务脚本的测试用例:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample2" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample2",
  "traceId": "3cf20f08fe7f4d0d8c320ea14b61c98e",
  "parentTraceId": null,
  "timestamp": 1646564189216,
  "data": {
    "message": "hello!",
    "accountNo": "003"
  }
}

3 个性化的Source接入模块

不是通过标准的开放OpenAPI接口上送服务请求,实现个性化接口调用/bean/sample2服务。

$ curl -H "Content-Type:application/json" -X POST --data '{"accountNo":"003"}' http://localhost:8080/source1|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample2",
  "traceId": "c4d06665d3114668bddaca096ca6ebf9",
  "parentTraceId": null,
  "timestamp": 1646564895713,
  "data": {
    "message": "hello!",
    "accountNo": "003"
  }
}

4 通过Sink透传App服务直接调用Sink服务

通过Biz-SIP的开放API接口,通过配置的Sink透传App服务,直接调用hello-sink服务。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/hello-sink" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/hello-sink",
  "traceId": "d310149f0f9d4df7824617235239210b",
  "parentTraceId": null,
  "timestamp": 1646706999650,
  "data": {
    "message": "hello!",
    "accountNo": "003"
  }
}

5 通过接口类方法调用App服务和Sink服务

通过开发的HelloSourceController接口,调用App服务和Sink服务,其中App服务和Sink服务,是采用Spring Bean类来实现的:

$ curl http://localhost:8080/hello?message=world

hello,world

6 简单XML消息转换

通过Biz-SIP的开放API接口,调用simple-xml-sink进行simple-xml报文的打包,接着调用EchoConnectorService打印消息报文并返回,通过simple-xml-sink解包成JSON报文后返回结果。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/simple-xml-sink" -X POST --data '{"accountName": "王五","balance": 500,"accountNo":"005"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/simple-xml-sink",
  "traceId": "dcad86b3294b49f09a6a79f196929e7a",
  "parentTraceId": null,
  "timestamp": 1647161094697,
  "data": {
    "accountName": "王五",
    "balance": 500,
    "accountNo": "005"
  }
}

simple-xml-sink接入EchoConnectorService类打印的消息:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D 22 31 2E 30 22 20 | <?xml version="1.0"  |
0020: 65 6E 63 6F 64 69 6E 67 3D 22 55 54 46 2D 38 22 20 73 74 61 | encoding="UTF-8" sta |
0040: 6E 64 61 6C 6F 6E 65 3D 22 6E 6F 22 3F 3E 3C 72 6F 6F 74 3E | ndalone="no"?><root> |
0060: 3C 61 63 63 6F 75 6E 74 4E 61 6D 65 3E E7 8E 8B E4 BA 94 3C | <accountName>王.五.< |
0080: 2F 61 63 63 6F 75 6E 74 4E 61 6D 65 3E 3C 62 61 6C 61 6E 63 | /accountName><balanc |
0100: 65 3E 35 30 30 3C 2F 62 61 6C 61 6E 63 65 3E 3C 61 63 63 6F | e>500</balance><acco |
0120: 75 6E 74 4E 6F 3E 30 30 35 3C 2F 61 63 63 6F 75 6E 74 4E 6F | untNo>005</accountNo |
0140: 3E 3C 2F 72 6F 6F 74 3E                                     | ></root>............ |

7 复杂JSON消息转换

通过Biz-SIP的开放API接口,调用velocity-json-sink进行velocity-json报文的打包,接着调用EchoConnectorService打印消息报文并返回,通过velocity-json-sink解包成JSON报文后返回结果。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/velocity-json-sink" -X POST --data '{"accountName": "王五","sex": "0","accountNo":"005"}' http://lalhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/velocity-json-sink",
  "traceId": "a01c500f69964d5b8b37b54e59822be7",
  "parentTraceId": null,
  "timestamp": 1647176026507,
  "data": {
    "sex": "女",
    "account_no": "005",
    "account_name": "王五"
  }
}

EchoConnectorService打印日志:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 7B 73 65 78 3A 22 E5 A5 B3 22 2C 61 63 63 6F 75 6E 74 5F 6E | {sex:"女.",account_n |
0020: 6F 3A 22 30 30 35 22 2C 61 63 63 6F 75 6E 74 5F 6E 61 6D 65 | o:"005",account_name |
0040: 3A 22 E7 8E 8B E4 BA 94 22 7D                               | :"王.五."}.......... |
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/velocity-json-sink" -X POST --data '{"accountName": "王五","sex": "1","accountNo":"005"}' http://lalhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/velocity-json-sink",
  "traceId": "f0861bfc07c64048ae2499c12030878a",
  "parentTraceId": null,
  "timestamp": 1647176026608,
  "data": {
    "sex": "男",
    "account_no": "005",
    "account_name": "王五"
  }
}

EchoConnectorService打印日志:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 7B 73 65 78 3A 22 E7 94 B7 22 2C 61 63 63 6F 75 6E 74 5F 6E | {sex:"男.",account_n |
0020: 6F 3A 22 30 30 35 22 2C 61 63 63 6F 75 6E 74 5F 6E 61 6D 65 | o:"005",account_name |
0040: 3A 22 E7 8E 8B E4 BA 94 22 7D                               | :"王.五."}.......... |
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/velocity-json-sink" -X POST --data '{"accountName": "王五","sex": "2","accountNo":"005"}' http://lalhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/velocity-json-sink",
  "traceId": "3c9f4c9207ae4875b05ef682f7882a2d",
  "parentTraceId": null,
  "timestamp": 1647176026756,
  "data": {
    "sex": "?",
    "account_no": "005",
    "account_name": "王五"
  }
}

EchoConnectorService打印日志:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 7B 73 65 78 3A 22 3F 22 2C 61 63 63 6F 75 6E 74 5F 6E 6F 3A | {sex:"?",account_no: |
0020: 22 30 30 35 22 2C 61 63 63 6F 75 6E 74 5F 6E 61 6D 65 3A 22 | "005",account_name:" |
0040: E7 8E 8B E4 BA 94 22 7D                                     | 王.五."}............ |

8 复杂XML消息转换

通过Biz-SIP的开放API接口,调用velocity-xml-sink进行velocity-xml报文的打包,接着调用EchoConnectorService打印消息报文并返回,通过velocity-xml-sink解包成JSON报文后返回结果。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/velocity-xml-sink" -X POST --data '{"accountName": "王五","sex": "0","accountNo":"005","balance":1}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/velocity-xml-sink",
  "traceId": "2146dd16d67e42c485e94678cfc13064",
  "parentTraceId": null,
  "timestamp": 1647176026824,
  "data": {
    "account": {
      "no": "005",
      "sex": "女人",
      "balance": 100,
      "name": "王五"
    }
  }
}

EchoConnectorService打印日志:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 3C 61 63 63 6F 75 6E 74 3E 0A 20 20 20 20 3C 6E 61 6D 65 3E | <account>.    <name> |
0020: E7 8E 8B E4 BA 94 3C 2F 6E 61 6D 65 3E 0A 20 20 20 20 3C 62 | 王.五.</name>.    <b |
0040: 61 6C 61 6E 63 65 3E 31 30 30 3C 2F 62 61 6C 61 6E 63 65 3E | alance>100</balance> |
0060: 0A 20 20 20 20 3C 6E 6F 3E 30 30 35 3C 2F 6E 6F 3E 0A 20 20 | .    <no>005</no>.   |
0080: 20 20 3C 73 65 78 3E E5 A5 B3 E4 BA BA 3C 2F 73 65 78 3E 0A |   <sex>女.人.</sex>. |
0100: 3C 2F 61 63 63 6F 75 6E 74 3E                               | </account>.......... |
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/velocity-xml-sink" -X POST --data '{"accountName": "王五","sex": "1","accountNo":"005","balance":10}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/velocity-xml-sink",
  "traceId": "8061430704b24a86953e9c8a26d1d7a4",
  "parentTraceId": null,
  "timestamp": 1647176026930,
  "data": {
    "account": {
      "no": "005",
      "sex": "男人",
      "balance": 1000,
      "name": "王五"
    }
  }
}

EchoConnectorService打印日志:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 3C 61 63 63 6F 75 6E 74 3E 0A 20 20 20 20 3C 6E 61 6D 65 3E | <account>.    <name> |
0020: E7 8E 8B E4 BA 94 3C 2F 6E 61 6D 65 3E 0A 20 20 20 20 3C 62 | 王.五.</name>.    <b |
0040: 61 6C 61 6E 63 65 3E 31 30 30 30 3C 2F 62 61 6C 61 6E 63 65 | alance>1000</balance |
0060: 3E 0A 20 20 20 20 3C 6E 6F 3E 30 30 35 3C 2F 6E 6F 3E 0A 20 | >.    <no>005</no>.  |
0080: 20 20 20 3C 73 65 78 3E E5 A5 B3 E4 BA BA 3C 2F 73 65 78 3E |    <sex>女.人.</sex> |
0100: 0A 3C 2F 61 63 63 6F 75 6E 74 3E                            | .</account>......... |
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/velocity-xml-sink" -X POST --data '{"accountName": "王五","sex": "2","accountNo":"005","balance":10}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/velocity-xml-sink",
  "traceId": "f778623432584b15878038e7db1d2bce",
  "parentTraceId": null,
  "timestamp": 1647176027027,
  "data": {
    "account": {
      "no": "005",
      "sex": "不知道",
      "balance": 1000,
      "name": "王五"
    }
  }
}

EchoConnectorService打印日志:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 3C 61 63 63 6F 75 6E 74 3E 0A 20 20 20 20 3C 6E 61 6D 65 3E | <account>.    <name> |
0020: E7 8E 8B E4 BA 94 3C 2F 6E 61 6D 65 3E 0A 20 20 20 20 3C 62 | 王.五.</name>.    <b |
0040: 61 6C 61 6E 63 65 3E 31 30 30 30 3C 2F 62 61 6C 61 6E 63 65 | alance>1000</balance |
0060: 3E 0A 20 20 20 20 3C 6E 6F 3E 30 30 35 3C 2F 6E 6F 3E 0A 20 | >.    <no>005</no>.  |
0080: 20 20 20 3C 73 65 78 3E E4 B8 8D E7 9F A5 E9 81 93 3C 2F 73 |    <sex>不.知.道.</s |
0100: 65 78 3E 0A 3C 2F 61 63 63 6F 75 6E 74 3E 0A                | ex>.</account>...... |

9 定长消息转换

通过Biz-SIP的开放API接口,调用fixed-length-sink用定长消息格式打包,然后会调用EchoConnectorService打印消息报文,并用原服文返回,在fixed-length-sink解包成JSON报文后返回。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/fixed-length-sink" -X POST --data '{"accountName": "王五","balance": 500,"accountNo":"005","sex":"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/fixed-length-sink",
  "traceId": "78b51f246e20451291713beda492ace8",
  "parentTraceId": null,
  "timestamp": 1647176027111,
  "data": {
    "accountName": "王五        ",
    "sex": "0",
    "balance": "500       ",
    "accountNo": "005     "
  }
}

EchoConnectorService类打印的消息:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 30 30 30 35 20 20 20 20 20 E7 8E 8B E4 BA 94 20 20 20 20 20 | 0005     王.五.      |
0020: 20 20 20 35 30 30 20 20 20 20 20 20 20                      |    500       ....... |

10 有分隔符消息转换

通过Biz-SIP的开放API接口,调用velocity-split-sink用定长消息格式打包,然后会调用EchoConnectorService打印消息报文,并用原服文返回,在velocity-split-sink解包成JSON报文后返回。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/velocity-split-sink" -X POST --data '{"accountName": "王五","balance": 500,"accountNo":"005","sex"0"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/velocity-split-sink",
  "traceId": "81f3b80f4ff04668bc17d18f633199b7",
  "parentTraceId": null,
  "timestamp": 1647176027220,
  "data": {
    "array": [
      [
        "0",
        "005"
      ],
      [
        "王五",
        "500"
      ]
    ]
  }
}

EchoConnectorServicer类打印的消息:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 30 2C 30 30 35 2A E7 8E 8B E4 BA 94 2C 35 30 30             | 0,005*王.五.,500.... |

11 ISO8583消息转换

通过Biz-SIP的开放API接口,调用iso-8583-sink进行ISO-8583报文的打包,然后会调用EchoConnectorServicer打印消息报文,并用原服文返回,在iso-8583-sink解包成JSON报文后返回。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/iso-8583-sink" -X POST --data '{"msgType": "0800","reserved60": "000000000030","card_accptr_id42": "898411341310014","systemTraceAuditNumber11": "000001","switching_data62": "53657175656e6365204e6f3132333036303733373832323134","card_accptr_termnl_id41": "73782214","msgHead": "31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536","acct_id_1_102": "1234567890","fin_net_data63": "303031"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/iso-8583-sink",
  "traceId": "9ffadf46d47849d2b353baec35d42ac7",
  "parentTraceId": null,
  "timestamp": 1647176027306,
  "data": {
    "msgType": "0800",
    "reserved60": "000000000030",
    "card_accptr_id42": "898411341310014",
    "systemTraceAuditNumber11": "000001",
    "switching_data62": "53657175656e6365204e6f3132333036303733373832323134",
    "card_accptr_termnl_id41": "73782214",
    "msgHead": "31323031383430303031303334342020203432343330343430202020393031323334353637383930313233343536",
    "acct_id_1_102": "1234567890",
    "fin_net_data63": "303031"
  }
}

EchoConnectorServicer类打印的消息:

收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +
0000: 31 32 30 31 38 34 30 30 30 31 30 33 34 34 20 20 20 34 32 34 | 12018400010344   424 |
0020: 33 30 34 34 30 20 20 20 39 30 31 32 33 34 35 36 37 38 39 30 | 30440   901234567890 |
0040: 31 32 33 34 35 36 30 38 30 30 80 20 00 00 00 C0 00 16 00 00 | 1234560800� ...�.... |
0060: 00 00 04 00 00 00 30 30 30 30 30 31 37 33 37 38 32 32 31 34 | ......00000173782214 |
0080: 38 39 38 34 31 31 33 34 31 33 31 30 30 31 34 30 31 32 30 30 | 89841134131001401200 |
0100: 30 30 30 30 30 30 30 30 33 30 30 35 30 35 33 36 35 37 31 37 | 00000000300505365717 |
0120: 35 36 35 36 65 36 33 36 35 32 30 34 65 36 66 33 31 33 32 33 | 5656e6365204e6f31323 |
0140: 33 33 30 33 36 33 30 33 37 33 33 33 37 33 38 33 32 33 32 33 | 33036303733373832323 |
0160: 31 33 34 30 30 36 33 30 33 30 33 31 31 30 31 32 33 34 35 36 | 13400630303110123456 |
0180: 37 38 39 30                                                 | 7890................ |

12 Sink模块通过API调用converter和connector

Sink模块(sample17-sink)在代码中,通过单独调用消息转换器converter和通讯适配器connector的API接口,实现调用配置好的消息转换器converter进行消息打包、消息解包,以及调用配置好的通讯适配器connector进行接口调用。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/sample17-sink" -X POST --data '{"accountName": "王五","sex": "0","accountNo":"005","balance":100}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/sample17-sink",
  "traceId": "73b1837286b44ede9c317040999a8607",
  "parentTraceId": null,
  "timestamp": 1646708971188,
  "data": {
    "account": {
      "no": "005",
      "sex": "女人",
      "balance": 100,
      "name": "王五"
    }
  }
}

13 Source模块通过API调用converter

Source模块(source4)在代码中,通过单独调用消息转换器converter,实现调用配置好的消息转换器converter进行消息打包、消息解包,并通过App服务调用的API接口,发起对App服务的调用。

$ curl -H "Content-Type:application/xml" -X POST --data '<?xml version="1.0" encoding="UTF-8" standalone="no"?><root><accountName>王五</accountName><balance>500</balance><accountNo>005</accountNo></root>' http://localhost:8080/source4

<?xml version="1.0" encoding="UTF-8" standalone="no"?><root><accountName>王五</accountName><balance>500</balance><accountNo>005</accountNo></root>

14 调用Netty Connector的Sink服务

通过Biz-SIP的开放API接口,调用Netty TCP服务端。

在终端1启动:

$ echo '{"accountName": "王五","balance": 500,"accountNo":"xxx"}'|nc -l 10010

在终端2启动:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/netty-sink" -X POST --data '{"accountNo":"999"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/netty-sink",
  "traceId": "88d6f7ce203d412b9e207ce7a808f856",
  "parentTraceId": null,
  "timestamp": 1647869711539,
  "data": {
    "accountName": "王五",
    "balance": 500,
    "accountNo": "xxx"
  }
}

15 调用RabbitMQ Connector的Sink服务

通过Biz-SIP的开放API接口,通过Sink直通App服务调用rabbitmq-connector-sink服务,通过RCP调用RabbitMQ消息中间件,被RabbitmqConnectorSinkQueueListener侦听类处理并同步返回。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/rabbitmq-connector-sink" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/rabbitmq-connector-sink",
  "traceId": "f06e5f11462244d5bdc9bba79512fee9",
  "parentTraceId": null,
  "timestamp": 1646902087939,
  "data": {
    "accountNo": "003"
  }
}

16 调用http-post Connector的Sink服务

通过Biz-SIP的开放API接口,通过Sink直通App服务调用http-connector-sink服务,通过http-post,和httpbin.org进行交互(httpbin.org是一个使用 Python + Flask 编写的 HTTP请求和响应服务网站)。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/http-connector-sink" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/sink/http-connector-sink",
  "traceId": "7fe37d688ec14415b32b0ad913df28f0",
  "parentTraceId": null,
  "timestamp": 1648279939290,
  "data": {
    "headers": {
      "Accept": "text/html,application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool",
      "Host": "httpbin.org",
      "Accept-Encoding": "gzip, deflate",
      "Pragma": "no-cache",
      "X-Amzn-Trace-Id": "Root=1-623ec183-2886791f5cf46db777b11e6a",
      "Cache-Control": "no-cache",
      "Accept-Language": "zh-CN,zh;q=0.8",
      "Content-Length": "19",
      "Content-Type": "application/json"
    },
    "data": "{\"accountNo\":\"003\"}",
    "origin": "101.80.178.194",
    "url": "http://httpbin.org/post",
    "args": {},
    "form": {},
    "files": {},
    "json": {
      "accountNo": "003"
    }
  }
}

17 基于Netty服务端的Source接入

通过Netty客户端接入,来调用聚合服务。

$ echo '{"serviceId":"/script/sample2","accountNo":"003"}'|nc localhost 10020

{"message":"hello!","accountNo":"003","serviceId":"/script/sample2"}

18 App服务通过RabbitMQ异步调用Sink服务

App服务通过(type: rabbitmq)方式异步调用rabbitmq-sink服务,App服务不会等待rabbitmq-sink服务的返回结果。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/rabbitmq-hello" -X POST --data '{"methodName":"hello","params":["world"]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/rabbitmq-hello",
  "traceId": "4da99c8f35f341e38ab03deea5974c78",
  "parentTraceId": null,
  "timestamp": 1648303982556,
  "data": {
    "result": "hello,world"
  }
}

19 App服务调用App延迟服务

通过Biz-SIP的开放API接口,调用App服务,App服务对App延迟服务进行多次的重试调用。

上送请求数据说明:

  • “maxRetryCount”为最大请求次数
  • “result”为最后的响应为成功还是失败。
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample15" -X POST --data '{"maxRetryCount":4,"result":"success"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample15",
  "traceId": "35a40e4bace44883bcb6511a3b016b82",
  "parentTraceId": null,
  "timestamp": 1648358690842,
  "data": {
    "maxRetryCount": 4,
    "result": "success"
  }
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample15" -X POST --data '{"maxRetryCount":3,"result":"fail"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample15",
  "traceId": "a60d017e00554dd6a779a478ced2c7f5",
  "parentTraceId": null,
  "timestamp": 1648359627667,
  "data": {
    "maxRetryCount": 3,
    "result": "fail"
  }
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample15" -X POST --data '{"maxRetryCount":8,"result":"success"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample15",
  "traceId": "19e559c658954b35861a32369b08f5b1",
  "parentTraceId": null,
  "timestamp": 1648359793722,
  "data": {
    "maxRetryCount": 8,
    "result": "success"
  }
}

20 调用数据库操作

通过Biz-SIP的开放API接口,在脚本服务中根据上送的账号在数据表中进行查询,并直接返回查询结果。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/script/sample10" -X POST --data '{"accountNo":"002"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/script/sample10",
  "traceId": "b629318a0f5547dc91585cc0dd10b8ab",
  "parentTraceId": null,
  "timestamp": 1646624300458,
  "data": {
    "array": [
      {
        "accountName": "李四",
        "sex": "1",
        "balance": 200,
        "accountNo": "002"
      }
    ]
  }
}

21 调用Redis操作

通过Biz-SIP的开放API接口,在脚本服务中根据上送的账号在Redis中进行存储,并直接返回查询结果。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/script/sample11" -X POST --data '{"accountNo":"002"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/script/sample11",
  "traceId": "51f2bbbbcd0e49df9f8f00c9c0c4a742",
  "parentTraceId": null,
  "timestamp": 1646624389838,
  "data": {
    "accountName": "002",
    "accountNo": "002"
  }
}
redis>get account_no
"002"

22 通过App延迟服务进行重试调用

通过Biz-SIP的开放API接口,在脚本服务中调用SAF服务,对server3服务进行多达5次的服务重试调用。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/script/sample12" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/script/sample12",
  "traceId": "217994a800754769816cd7ef7dd21b72",
  "parentTraceId": null,
  "timestamp": 1646698543479,
  "data": {
    "accountNo": "003"
  }
}

SampleSinkApplication日志:

[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:45.821 DEBUG 50912 [AA990912E46A44C7934469AD59AFD74B] [http-nio-8888-exec-6] c.bizmda.bizsip.app.service.AppService   开始处理App服务: /script/sample12
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:45.821 DEBUG 50912 [AA990912E46A44C7934469AD59AFD74B] [http-nio-8888-exec-6] c.bizmda.bizsip.app.service.AppService   调用App服务[/script/sample12]: traceId=966e65be372a42c18f3098b500134788
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:45.823 DEBUG 50912 [AA990912E46A44C7934469AD59AFD74B] [http-nio-8888-exec-6] c.b.bizsip.app.service.AppClientService  入参:/script/sample12-1,{"accountNo":"003"},[0, 2000, 4000, 8000, 16000]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:45.825 DEBUG 50912 [AA990912E46A44C7934469AD59AFD74B] [http-nio-8888-exec-6] c.b.bizsip.app.service.AppClientService  发送交易挂起日志
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:45.825 DEBUG 50912 [AA990912E46A44C7934469AD59AFD74B] [http-nio-8888-exec-6] c.bizmda.bizsip.app.service.AppService   发送交易成功日志
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:45.837 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-99] c.b.b.a.l.DelayAppServiceQueueListener   收到延迟App服务[/script/sample12-1]: 第1次,延迟时间[[0, 2000, 4000, 8000, 16000]]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:45.837 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-99] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:46.081 WARN 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-99] c.b.b.app.executor.ScriptAppExecutor     sip.timeout():调用timeout()导致超时错误!
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:46.082 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-99] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]:第2次,延迟时间[2000ms]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:46.084 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-99] c.b.b.a.l.DelayAppServiceQueueListener   发送交易挂起日志
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:48.106 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-98] c.b.b.a.l.DelayAppServiceQueueListener   收到延迟App服务[/script/sample12-1]: 第2次,延迟时间[[0, 2000, 4000, 8000, 16000]]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:48.107 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-98] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:48.144 WARN 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-98] c.b.b.app.executor.ScriptAppExecutor     sip.timeout():调用timeout()导致超时错误!
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:48.144 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-98] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]:第3次,延迟时间[4000ms]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:48.145 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-98] c.b.b.a.l.DelayAppServiceQueueListener   发送交易挂起日志
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:52.253 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-97] c.b.b.a.l.DelayAppServiceQueueListener   收到延迟App服务[/script/sample12-1]: 第3次,延迟时间[[0, 2000, 4000, 8000, 16000]]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:52.254 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-97] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:52.277 WARN 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-97] c.b.b.app.executor.ScriptAppExecutor     sip.timeout():调用timeout()导致超时错误!
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:52.278 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-97] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]:第4次,延迟时间[8000ms]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:17:52.279 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-97] c.b.b.a.l.DelayAppServiceQueueListener   发送交易挂起日志
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:00.288 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-96] c.b.b.a.l.DelayAppServiceQueueListener   收到延迟App服务[/script/sample12-1]: 第4次,延迟时间[[0, 2000, 4000, 8000, 16000]]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:00.288 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-96] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:00.307 WARN 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-96] c.b.b.app.executor.ScriptAppExecutor     sip.timeout():调用timeout()导致超时错误!
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:00.307 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-96] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]:第5次,延迟时间[16000ms]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:00.308 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-96] c.b.b.a.l.DelayAppServiceQueueListener   发送交易挂起日志
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:16.316 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-100] c.b.b.a.l.DelayAppServiceQueueListener   收到延迟App服务[/script/sample12-1]: 第5次,延迟时间[[0, 2000, 4000, 8000, 16000]]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:16.316 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-100] c.b.b.a.l.DelayAppServiceQueueListener   调用延迟App服务[/script/sample12-1]
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:16.345 WARN 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-100] c.b.b.app.executor.ScriptAppExecutor     sip.error():自定义错误!
[bizsip-integrator:192.168.20.14:8888] 2022-03-08 08:18:16.346 DEBUG 50912 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-100] c.b.b.a.l.DelayAppServiceQueueListener   发送交易失败日志

23 App服务调用基于Script的延迟服务

通过Biz-SIP的开放API接口,通过Java开发的App服务,调用App延迟服务,对echo-sink服务进行多达5次的服务重试调用。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample13" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample13",
  "traceId": "ecb84958c1734e0fb3a394b25df6fbe7",
  "parentTraceId": null,
  "timestamp": 1646699271134,
  "data": {
    "accountNo": "003"
  }
}

24 App服务通过AppClientFactory.getSinkClient()调用Sink服务

通过Biz-SIP的开放API接口,调用以Java接口方式暴露的Sink服务。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample14" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample14",
  "traceId": "dd88ed4bda204cd8a0bddb1eaff4200e",
  "parentTraceId": null,
  "timestamp": 1646700992823,
  "data": {
    "customerDTO": {
      "sex": "1",
      "customerId": "001",
      "name": "张三",
      "age": 20
    },
    "hello-sink": {
      "message": "hello!",
      "accountNo": "003"
    },
    "accountDTOs": [
      {
        "balance": 1200,
        "account": "0001"
      },
      {
        "balance": 45000,
        "account": "0003"
      }
    ],
    "accountDTOList": [
      {
        "balance": 3400,
        "account": "0002"
      },
      {
        "balance": 77800,
        "account": "0004"
      }
    ],
    "result1": "doService1() result"
  }
}

25 调用Bean类型App服务和Bean类型Sink服务

通过Biz-SIP的开放API接口,调用App服务关联类,并在类中调用Sink服务关联类。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample16" -X POST --data '{"methodName":"doService1","params":["003"]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample16",
  "traceId": "cc8ab1ffe34b4bf68ae076b17cee384e",
  "parentTraceId": null,
  "timestamp": 1646706451144,
  "data": {
    "result": "doService1() result"
  }
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample16" -X POST --data '{"methodName":"doService2","params":["003",1]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample16",
  "traceId": "2fa0d40228e548ae97446182bd046a29",
  "parentTraceId": null,
  "timestamp": 1646706509605,
  "data": {}
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample16" -X POST --data '{"methodName":"queryCustomerDTO","params":["003"]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample16",
  "traceId": "c8b658e2b23443169a082a59d510ecaa",
  "parentTraceId": null,
  "timestamp": 1646706552686,
  "data": {
    "result": {
      "sex": "1",
      "customerId": "001",
      "name": "张三",
      "age": 20
    }
  }
}

26 App服务的域校验和服务校验

通过Biz-SIP的开放API接口发送请求,在App服务调用前,会根据配置进行域级校验和服务级校验,校验出错会返回出错信息,校验通过后,会调用App服务后直接返回。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-check-rule" -X POST --data '{"accountNo":"62001818","sex":"0","email":"123232@163.com","mobile":"18601872345"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample1-check-rule",
  "traceId": "ad6765833c2847a3912cf836e25c91d9",
  "parentTraceId": null,
  "timestamp": 1647845790993,
  "data": {
    "sex": "0",
    "mobile": "18601872345",
    "accountNo": "62001818",
    "email": "123232@163.com"
  }
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-check-rule" -X POST --data '{"accountNo":"62001818","sex":"0","email":"123232","mobile":"18601872345"}' http://localhost:8888/api|jq

{
  "code": 307,
  "message": "域校验出错",
  "extMessage": "[{\"message\":\"不是邮箱地址:123232\",\"field\":\"email\"}]",
  "appServiceId": "/bean/sample1-check-rule",
  "traceId": "b11f60ef602b475daea510bcfffea2ba",
  "parentTraceId": null,
  "timestamp": 1647845791036,
  "data": null
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-check-rule" -X POST --data '{"accountNo":"62001818","sex":"0","email":"123232@163.com","mobile":"021-34554345"}' http://localhost:8888/api|jq

{
  "code": 307,
  "message": "域校验出错",
  "extMessage": "[{\"message\":\"不是手机号021-34554345\",\"field\":\"mobile\"}]",
  "appServiceId": "/bean/sample1-check-rule",
  "traceId": "41a2013c94f84339922891cbf65b8954",
  "parentTraceId": null,
  "timestamp": 1647845791073,
  "data": null
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-check-rule" -X POST --data '{"accountNo":"62001818","email":"123232@163.com","mobile":"18601872345"}' http://localhost:8888/api|jq

{
  "code": 307,
  "message": "域校验出错",
  "extMessage": "[{\"message\":\"不能为空\",\"field\":\"sex\"}]",
  "appServiceId": "/bean/sample1-check-rule",
  "traceId": "83f21fd288c6474c953b2531a68737fb",
  "parentTraceId": null,
  "timestamp": 1647845791105,
  "data": null
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-check-rule" -X POST --data '{"accountNo":"62001818","sex":"0","email":"123232@163.com","mobile":"18601872345","age":20}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample1-check-rule",
  "traceId": "06bb9d1d714c4ee78cd309eecd216b20",
  "parentTraceId": null,
  "timestamp": 1648699339934,
  "data": {
    "sex": "0",
    "mobile": "18601872345",
    "accountNo": "62001818",
    "email": "123232@163.com",
    "age": 20
  }
}

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-check-rule" -X POST --data '{"accountNo":"62001818","sex":"0","email":"123232@163.com","mobile":"18601872345","age":55}' http://localhost:8888/api|jq

{
  "code": 312,
  "message": "服务规则校验出错",
  "extMessage": "[{\"message\":\"女性年龄大于50岁!\"}]",
  "appServiceId": "/bean/sample1-check-rule",
  "traceId": "67b19f640c3b4a6d962d97e55f95e368",
  "parentTraceId": null,
  "timestamp": 1648699555359,
  "data": null
}

27 调用风控模块

调用服务关联的风控模块,进行指标查询、指标增加、指标删除的操作。

1、针对“每分钟交易次数超过3次”的风控规则测试:

首先,连续在一分钟内连接执行以下请求:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-control-rule" -X POST --data '{"account":"001","amount":100,"other_account":"002"}' http://localhost:8888/api|jq

{
"code": 0,
"message": "success",
"extMessage": null,
"appServiceId": "/bean/sample1-control-rule",
"traceId": "88a648f8fd3a4701a250e206e31c08cb",
"parentTraceId": null,
"timestamp": 1649060116207,
"data": {
"amount": 100,
"other_account": "002",
"account": "001"
}
}

在60秒内第4次执行,会出现风控规则校验不通过的错误:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-control-rule" -X POST --data '{"account":"001","amount":100,"other_account":"002"}' http://localhost:8888/api|jq

{
"code": 501,
"message": "风控规则检查不通过",
"extMessage": "每分钟交易次数超过3次:4,",
"appServiceId": "/bean/sample1-control-rule",
"traceId": "a78178519e5e4761bd2de3293a78a86c",
"parentTraceId": null,
"timestamp": 1649060120530,
"data": null
}

2、针对“每分钟交易金额超过1000元”的风控规则测试:

首先,连续在一分钟内连接执行以下请求:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-control-rule" -X POST --data '{"account":"001","amount":500,"other_account":"002"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample1-control-rule",
  "traceId": "09b20bf20882459084ca156fc9652373",
  "parentTraceId": null,
  "timestamp": 1649060560647,
  "data": {
    "amount": 500,
    "other_account": "002",
    "account": "001"
  }
}


在60秒内第4次执行,会出现风控规则校验不通过的错误:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-control-rule" -X POST --data '{"account":"001","amount":500,"other_account":"002"}' http://localhost:8888/api|jq

{
  "code": 501,
  "message": "风控规则检查不通过",
  "extMessage": "每分钟交易金额超过1000元:1500,",
  "appServiceId": "/bean/sample1-control-rule",
  "traceId": "10fd1a0f07b64def8f7d69267aaa222c",
  "parentTraceId": null,
  "timestamp": 1649060563862,
  "data": null
}

3、针对“每分钟交易对手数量超过2个”的风控规则测试:

首先,连续在一分钟内连接执行以下请求,其中”other_account“分别填写不同的值:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-control-rule" -X POST --data '{"account":"001","amount":500,"other_account":"002"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/sample1-control-rule",
  "traceId": "18bbd4fb9c8e405195375190094728d0",
  "parentTraceId": null,
  "timestamp": 1649060818309,
  "data": {
    "amount": 500,
    "other_account": "002",
    "account": "001"
  }
}

在60秒内第4次执行,会出现风控规则校验不通过的错误:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample1-control-rule" -X POST --data '{"account":"001","amount":500,"other_account":"005"}' http://localhost:8888/api|jq

{
  "code": 501,
  "message": "风控规则检查不通过",
  "extMessage": "每分钟交易金额超过1000元:1500,每分钟交易对手数量超过2个:3,",
  "appServiceId": "/bean/sample1-control-rule",
  "traceId": "a9423171d06947c09d555756e614405a",
  "parentTraceId": null,
  "timestamp": 1649060831138,
  "data": null
}

28 基于Netty的TCP异步长连接

基于Netty的TCP异步长连接,支持拆包粘包,并实现了心跳检测。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/long-tcp-netty" -X POST --data '{"accountNo":"003"}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "appServiceId": "/bean/long-tcp-netty",
  "traceId": "c16c7a2e11804270b7836f5cd08c2b01",
  "parentTraceId": null,
  "timestamp": 1646713451080,
  "data": {
    "accountNo": "003",
    "replyTo": "amq.rabbitmq.reply-to.g1h2AA5yZXBseUA3ODA0MzU4OAAAXREAAAAqYdacFQ==.XsKFE7d1Yt8qYbLTVgy9vg==",
    "correlationId": "4"
  }
}
下一页