基于云的票务系统演进之【核验前置机】

293 阅读6分钟

一、背景简介

前两天接到一个项目是对当前核验系统升级改造,解决几个核心痛点及问题

  • 现场部署服务无法实现高可用性,只能单机服务;
  • 增强现场稳定性保障核验服务与数据能准确无误;
  • 对于核验能够提供全视角观测能力,在事前、事中、事后都能够查询状态;
  • 核验系统能够支持脱离公网环境独立运行;

二、演进前后架构

2.1 原有架构

2.2 新设计架构

  • 描述:现场部署以入场口为最小部署单元,最小部署单元具备独立的业务能力,并允许在无网络的情况下保证业务可用性(核验,高可用)。
  • fe与云端通讯方式:现场最小单元通过场馆有线(公网)/5G/iot 与云端通讯,目前场馆提供的有线网络为主要手段,如无有线,使用蜂窝网络,如人群数量巨大造成蜂窝网络阻塞,使用iot与云端通讯。
  • fe与edge的通讯方式:与edge可通过公网ip,vpc,公网网关与edge通讯。
  • 最小单元包含,闸机,路由器,前置机(边缘节点)。
  • 数据流转:端设备通过sdk实现日志上报给fe,由fe(flume或任何cdc如sync)通过edge或者有线网络上报给edge作为边缘计算的数据接入点,或直接通过场馆公网上报。如没有网络需上传至局域网中心服务(lora)
  • 数据下发:通过edge节点下发给容器configMap,由fe承接做后续动作或转发给设备端。
  • 高可用:前置机由edge管控可维持app的副本数(含无网络情况),目前mariadb,hiveMqtt,xxx-acs-xxx已经容器化,可保证单node上的HA。如需多node支持,则edge可根据节点池写tag,相同的tag认为是一套边缘节点,可部署高可用服务集群。

三、实施落地

3.1 高可用性

  • 环境需求
  1. Java应用xxx-acs-xxx数据库、MQ配置IP地址尽可能要固定;
  2. 边缘节点在接入时能够把预装组件和基础镜像都下载安装完成,并加入到edge集群资源池;(同时验证节点带到其它地域连网后可以正常使用,不需要删除重加)
  3. 边缘节点开启自治,保障在节点上运行的服务在异常后还可以正常拉起并运行;
  • 部署架构

  • 部署代码
服务名称IP 地址备注
xxx-acs-xxxIP地址 192.168.95.90 端口 8080
hivemqIP地址 192.168.95.90 端口 1883 映射端口:XXXX端口 8088、端口 8000
mariadbIP地址 192.168.95.90 端口 3306 映射端口:XXXX用户为root,密码
管理工具http://192.168.95.90:9000/admin xxxxxxxxx
apiVersion: apps/v1
kind: DaemonSet
metadata:
  annotations:
    apps.openyurt.io/update-strategy: AdvancedRollingUpdate
    apps.openyurt.io/max-unavailable: 30%
    stack: java
    workload: xxx-acs-xxx
  labels:
    app: xxx-acs-xxx
    stack: java
    version: prod
    workload: xxx-acs-xxx
  name: xxx-acs-xxx
  namespace: prod
spec:
  selector:
    matchLabels:
      stack: java
      workload: xxx-acs-xxx
  template:
    metadata:
      annotations:
        stack: java
        workload: xxx-acs-xxx
      labels:
        app: xxx-acs-xxx
        stack: java
        version: prod
        workload: xxx-acs-xxx
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              - key: alibabacloud.com/nodepool-id
                operator: In
                values:
                - np2b4819653fbe4c31b1fe295c3a1864e2
            weight: 100
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nodepool.openyurt.io/hostnetwork
                operator: In
                values:
                - "false"
      hostNetwork: true
      containers:
      - command:
        - java
        - -Dfile.encoding=UTF-8
        - -server
        - -XX:+UseContainerSupport
        - -XX:InitialRAMPercentage=65.0
        - -XX:MaxRAMPercentage=65.0
        - -XX:+UseConcMarkSweepGC
        - -XX:+PrintGCDetails
        - -XX:+PrintGCDateStamps
        - -Xdebug
        - -Xrunjdwp:transport=dt_socket,address=20000,server=y,suspend=n
        - -Duser.language=zh
        - -jar
        - /data/code/ROOT.jar
        env:
        - name: POD_PORT
          value: "8080"
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        - name: NODE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        envFrom:
        - configMapRef:
            name: runtime
        image: h
        imagePullPolicy: IfNotPresent
        lifecycle:
          preStop:
            exec:
              command:
              - /bin/bash
              - -x
              - pullOut.sh
        livenessProbe:
          failureThreshold: 2
          httpGet:
            path: /actuator/health
            port: 8080
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        name: xxx-acs-xxx
        ports:
        - containerPort: 8080
          hostPort: 8080
          protocol: TCP
          name: main-port
        readinessProbe:
          failureThreshold: 2
          httpGet:
            path: /actuator/health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 9
          successThreshold: 1
          timeoutSeconds: 2
        resources:
          limits:
            cpu: "3"
            memory: 2Gi
          requests:
            memory: 768Mi
        securityContext:
          allowPrivilegeEscalation: false
          privileged: false
          procMount: Default
          readOnlyRootFilesystem: false
          runAsNonRoot: false
        startupProbe:
          failureThreshold: 30
          httpGet:
            path: /actuator/health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /data/code/
          name: service-code
      dnsPolicy: ClusterFirst
      hostname: xxx-acs-xxx
      imagePullSecrets:
      - name: default-secret
      initContainers:
      - command:
        - cp
        - -a
        - /opt/ROOT.jar
        - /data/code/
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        image: h
        imagePullPolicy: IfNotPresent
        name: copy-code
        resources:
          requests:
            memory: 20Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /data/code/
          name: service-code
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 95
      volumes:
      - emptyDir: {}
        name: service-code

3.2 核验控制台

  • 控制台监控

核验控制台原理接近抢票控制台

  • 事前

    • 核验数据与订单比对,48h,24h,12h,6h,3h,1.5h,30s各执行一次,包含实名信息(sql已有),比对错误生成比对结果,人工介入处理。可随时手动跑
    • 人工核对核验规则,规则版本号。规则版本号为新概念,表述了核验规则最终的生效版本,由云端确认,同步给前置机。
    • 拉起核验沙盒(xxx-acs-xxx),设定时间为核验开始时间,对现有所有的票进行核验,生成结果人工核对。沙盒设计见下一节。
  • 到现场

    • 前置机加入边缘节点,同步核验数据。
    • 比对数据,核验规则版本号,边缘节点加入后自动启动app,sync后,启动比对,结果上报。
  • 现场部署硬件部署完毕

    • 端自检结果上报,自动从前置机同步配置信息,并核对当前客户端版本号,上报。(安卓自动更新app,是否可做)
    • 现场测试,生产项目测试数据(是否可做),或测试项目验证硬件与前置机。
  • 事中

    • 业务核验监控大屏,边缘节点大屏,关键接口健康状态
    • 核验数据,订单,即,用户数据 -> 所有系统数据的查询信息。(身份证查询票,票吗查询等),可支持手机。即快速定位用户是否有票,如确定,其实核验数据后续可补。
    • 对于业务规则变更原则上走全量沙盒验证,核验中可抽取验证。
    • 预案核验预案:同步预案:有全量同步接口
  • 事后。。。。

3.3 核验沙盒

描述:沙盒可看成离线前置机核验全量票。

对于人脸等操作进行mock处理,或使用系统中现有照片。

  1. 根据项目的xxx-acs-xxx镜像拉起一套核验离线服务端(xxx-acs-xxx,mqtt,mariadb)
  2. xxx-acs-xxx启动后从云端拉取核验数据,项目数据,规则数据。
  3. 当xxx-acs-xxx ready,使用核验信息,调用fe,测试票的可通过性。上报结果,日志,并销毁沙盒。
  4. 安卓业务端也可纳入,需讨论可行性。