精华内容
下载资源
问答
  • 关于上报数据的通知
    千次阅读
    2018-09-03 21:00:08

    目前有很多需求需要面对移动客户端在无网络环境下进行业务处理的情况(虽然听起来很神奇的,现在4G时代马上要迎来5G时代了,然而还是有很多情况和地区没有办法让移动设备联网),因此在处理这类问题时如何保证移动终端数据与服务端数据一致成为了一个待解决的问题。

    我们通过绘制场景并增加状态机和异常处理来解决以上问题

     

    手绘框架图

    1.当用户点击提交按钮时,客户端检测到网络不通,则将用户填写的数据存贮在本地存储中,并将数据状态设置为待提交状态;

    2.用户在查询时可以看到本地的待提交数据,并可以对待提交数据进行修改;

    3.当用户可以联网时,这时候数据还未提交,从服务端获取实时数据,查询列表中显示的是web数据和本地待提交数据的和;

    4.(进入查询、或手动点击同步数据后)将所有本地待提交数据生成离线提交文件,并将本次提交数据的状态设置为提交中状态,此时这些数据不能被修改。打包成文件提交的目的是增加提交事务处理功能,因为此次提交很可能由于网络不稳定而失败,因此需要事务来保证数据的一致性。

    5.服务端后去文件后立刻放回收到成功的状态,此时客户端收到数据后可以将提交中的数据删除。(短时间内客户端与服务端数据仍然一致,不过总数量少于实际数据数量,因为提交的数据还待服务端进行数据处理,由于服务端采用异步多道同时处理,因此很快可以达到服务端与客户端的数据一致)

    6.服务端快速处理异步提交的数据,成功直接入库,失败的需要根据用户账号,通过消息推送通知用户失败的离线数据,其中由于数据不一致的数据,需要用户确认是用自己的数据覆盖已有数据还是采用当前服务端数据;由于坏数据造成的数据处理异常,需要用户确认删除出错数据还是补充修改坏数据。

     

    通过以上处理流程,可以基本满足业务上离线处理需求。

    有问题请扫码提问

     

     

    更多相关内容
  • 数据上报那些事

    2021-10-14 15:23:05
    直观来说,要解决数据上报的时效性问题似乎很简单:实时上报(当触发事件后立刻上报到服务端)不就可以保证时效性了吗?但是,事实并非如此简单。 不同于服务端,移动设备上的资源是非常有限的,采取实时上报的方式...

    1. 前言

    神策分析是依托于数据进行的,数据是分析的根基。因此,数据上报的时效性是至关重要的。那么 iOS SDK(后面简称 SDK)是如何保证数据上报的时效性呢?

    接下来,我们就围绕这个问题来看看 SDK 究竟做了什么。

    2. 上报策略

    直观来说,要解决数据上报的时效性问题似乎很简单:实时上报(当触发事件后立刻上报到服务端)不就可以保证时效性了吗?但是,事实并非如此简单。

    不同于服务端,移动设备上的资源是非常有限的,采取实时上报的方式势必会造成 App 整体性能的下降,如何平衡性能与数据上报的时效性是 SDK 需要面临的一个挑战。

    目前 SDK 中使用的数据上报策略是事件触发后不立即上报,而是先将事件缓存在本地,然后满足一定的条件再进行上报。

    SDK 每次触发事件时会检查如下条件,用于判断是否向服务端上报数据:

    1. 当前网络是否符合发送策略 flushNetworkPolicy(默认 3G、4G、5G、WiFi);
    2. 与上次发送的时间间隔是否大于指定的时间间隔 flushInterval(默认 15 秒); 
    3. 本地缓存的事件条数是否大于最大缓存事件数 flushBulkSize(默认 100 条)。 

    只有 1、2 或者 1、3 满足时,SDK 才会发送数据。当然,为了满足不同的需求,可以通过修改 flushNetworkPolicy、flushInterval、flushBulkSize 的值来控制事件上报。

    SDK 的数据上报流程如图 2-1 所示:

     

    图 2-1 SDK 的数据上报流程图

    3. 时效性优化

    按照我们指定的上报策略进行数据上报,对于一般的自定义埋点事件及全埋点事件是可以满足时效性的要求。但是,这种上报策略存在一些弊端:

    1. App 退到后台或终止后如果不再打开,最后未上报的数据不会及时地上报到神策分析平台;
    2. 无法满足一些事件的实时上报需求。

    为了解决这两个问题,SDK 进行了如下的优化。

    3.1. App 进入后台时上报

    3.1.1. iOS 后台机制

    在了解 App 进入后台时如何上报之前,我们先来看下 iOS 的后台机制。iOS 系统中,App 在执行时可能会出现 ActiveInactiveBackgroundNot RunningSuspended 这几种状态[1]。当我们的 App 由前台进入到后台时,会有 5 秒的时间执行任务,在此后 App 将被系统置为挂起状态(Suspended)。此时 App 运行在后台,但无法执行代码。

    对于大多数 App 来说,5 秒的时间足够执行一些进入后台的关键任务。考虑一些 App 需要更多后台时间来处理任务,iOS 提供了用于延长应用后台执行时间[2] 的接口,可以申请额外的后台运行时间以保证任务执行完成。经过测试,在 iOS 12 及以上的系统最多可以申请 30 秒的运行时间。

    3.1.2. 后台数据上报

    我们已经知道 App 在进入后台时会在很短的时间内被系统挂起,由于数据上报时网络环境的不确定性,很难保证 SDK 在 5 秒时间内完成数据上报。因此,SDK 在 App 进入后台时会主动申请 App 后台任务。代码如下所示:

    UIApplication *application = UIApplication.sharedApplication;

    __block UIBackgroundTaskIdentifier backgroundTaskIdentifier = UIBackgroundTaskInvalid;

    void (^endBackgroundTask)(void) = ^() {

        [application endBackgroundTask:backgroundTaskIdentifier];

        backgroundTaskIdentifier = UIBackgroundTaskInvalid;

    };

    backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:endBackgroundTask];

    dispatch_async(self.serialQueue, ^{

      // 上传所有的数据

     [self.eventTracker flushAllEventRecords];

      // 结束后台任务

      endBackgroundTask();

    });

    3.2. App 终止时上报

    上一节讲述了 App 进入后台时如何进行数据上报,如果 App 终止了,数据还能及时上报吗?答案是肯定的。

    App 终止之前,系统会先发出 UIApplicationDidEnterBackgroundNotification 通知。此时,SDK 会申请后台任务进行数据入库及上报。

    接下来,系统就会立刻尝试终止后台任务,而 SDK 采集的退出事件($AppEnd)以及退到后台时采集的一些自定义事件可能没有足够的时间入库。这种情况不但无法完成数据上报,甚至会导致数据丢失。因此,我们需要在 App 即将终止时获得一段时间用于保存我们的事件数据。

    在 App 即将终止时系统会发出 UIApplicationWillTerminateNotification[3] 通知。因此,我们只要监听该通知并阻塞当前线程,从而完成数据保存及上报。代码如下所示:

    - (void)applicationWillTerminateNotification:(NSNotification *)notification {

        dispatch_sync(self.serialQueue, ^{});

    }

    3.3. 主动上报

    在 SDK 的预置事件里,有一些预置事件对时效性要求比较高。例如:用来分析 UV(日活)的 $AppStart(App 启动)事件,我们希望可以实时分析到真实的 UV 数据。因此,在触发 $AppStart 事件时 SDK 会主动上报一次数据。

    3.4. 手动上报

    由于 SDK 主动上报只能针对一些预置事件做处理,因此 SDK 对外提供了一个接口用于自定义事件的主动上报。代码如下所示:

    // 触发自定义事件

    ...

    [[SensorsAnalyticsSDK sharedInstance] flush];

    4. 踩过的坑

    通过上面的介绍可以知道,SDK 采取了很多方式用于保证数据上报的时效性。看起来似乎已经很完美了,但是在测试过程中还是发现了一些问题...

    4.1. App 终止时导致的问题

    在测试过程中遇到一个问题:当 App 终止时,数据上报出现了崩溃。

    此时,我们不免会有疑问:只是数据上报为什么会造成崩溃?真的是 SDK 的原因造成的吗?带着这些疑问我们分析了崩溃堆栈。如图 4-1 所示:

     

    图 4-1 Watchdog 造成的系统强杀

    首先,我们看到崩溃的原因是触发了系统的 Watchdog[4] 机制从而导致 App 被系统强杀,而此时 SDK 正在执行数据上报任务。

    结合 SDK 源码我们发现:App 终止时 SDK 为了保证数据上报成功,会采取阻塞当前线程的方式来延长 App 后台存活时间。代码如下所示:

    - (void)applicationWillTerminateNotification:(NSNotification *)notification {

        dispatch_sync(self.serialQueue, ^{});

    }

    而在弱网环境下数据可能一直无法上报成功,最终触发系统的 Watchdog 机制,从而导致崩溃。

    问题原因我们已经明白了,但是修复这个问题会涉及到 “鱼和熊掌不可兼得” 的问题:是保证数据及时上传还是保证 App 不触发 Watchdog 机制?

    由于这个场景是在 App 终止时发生的,本身并不会影响使用 App 的体验。其次,由于只在弱网环境下出现,发生的概率较小。因此,在之前版本的 SDK 默认会强制上报所有数据,同时提供手动关闭的接口,关闭后退到后台时不再上报数据。代码如下所示:

    // 关闭后台上报

    options.flushBeforeEnterBackground = NO;

    4.2. 事件上报导致的问题

    同样是弱网问题。由于 SDK 数据上报和数据采集是在同一个串行队列,数据上报时会阻塞该队列,导致数据无法正常入库,此时 App 终止可能会造成数据丢失。

    数据是分析的根基,保证数据不丢失是神策的红线。

    鉴于 iOS 系统对后台任务愈发严格的要求以及强制上报数据造成的影响,最终我们决定重构后台上报的逻辑。主要有以下几点变化:

    1. flushBeforeEnterBackground 作用改变,由退到后台是否上报数据更改为是否同步上报数据;
    2. flushBeforeEnterBackground 默认值修改为 NO(即异步上报),不再阻塞当前线程。

    代码如下所示:

    - (void)flushEventRecords:(NSArray<SAEventRecord *> *)records completion:(void (^)(BOOL success))completion {

        __block BOOL flushSuccess = NO;

        // 当设置 flushBeforeEnterBackground 为 YES 或 debug 模式下,使用线程锁

        BOOL isWait = self.flushBeforeEnterBackground || self.isDebugMode;

        [self requestWithRecords:records completion:^(BOOL success) {

            if (isWait) {

                flushSuccess = success;

                dispatch_semaphore_signal(self.flushSemaphore);

            else {

                completion(success);

            }

        }];

        if (isWait) {

            dispatch_semaphore_wait(self.flushSemaphore, DISPATCH_TIME_FOREVER);

            completion(flushSuccess);

        }

    }

    这段代码的含义如下:

    1. 如果 flushBeforeEnterBackground = YES,- flushEventRecords:completion: 方法为同步执行。当方法执行完成时,意味着数据上传也完成了;
    2. 如果 flushBeforeEnterBackground = NO,- flushEventRecords:completion:  方法为异步执行,不会等待数据上传完成,等数据上报完成后主动结束后台任务即可,代码如下所示:

      if (newState == SAAppLifecycleStateEnd) {

          UIApplication *application = UIApplication.sharedApplication;

          __block UIBackgroundTaskIdentifier backgroundTaskIdentifier = UIBackgroundTaskInvalid;

          void (^endBackgroundTask)(void) = ^() {

              [application endBackgroundTask:backgroundTaskIdentifier];

              backgroundTaskIdentifier = UIBackgroundTaskInvalid;

          };

          backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:endBackgroundTask];

          dispatch_async(self.serialQueue, ^{

              // 上传所有的数据

              [self.eventTracker flushAllEventRecordsWithCompletion:^{

                  // 结束后台任务

                  endBackgroundTask();

              }];

          });

          return;

      }

    目前,SDK 中 flushBeforeEnterBackground 默认值即为 NO。但是,这样会引入另外一个问题:在弱网环境下,可能会重复上报事件。原因如下:

    1. SDK 只会在服务端返回成功时才会删除本地保存的数据;
    2. 异步上报数据发起网络请求后就会继续执行下一个任务;
    3. 在弱网环境下可能服务端已经接收到数据但 SDK 没有接收到返回成功,此时 App 终止会导致无法删除本地保存的数据;
    4. 下次启动 App 时会重新上报该数据导致重复上报。

    这个问题可以通过服务端去重机制解决,保证相同数据不会重复入库。

    5. 总结

    数据分析是个复杂的系统,需要保证每一个环节都不会出错。

    在数据上报这一环节,关于时效性的优化我们一直在努力,并且一定会持续下去。

    6. 参考文献

    [1] Apple Developer Documentation 

    [2] Apple Developer Documentation

    [3] Apple Developer Documentation

    [4] Apple Developer Documentation

    文章来源公众号——神策技术社区

    展开全文
  • 3.组织上报数据实体格式如下 public class payExchangeInfoLists { public string orderNo { get; set; }//String 订单编号 public List<goodsInfo> goodsInfo { get; set; }// List 商品信息 public string ...
  • sea-monitorStargazers over timeN9E ...会放入队列,消息发送线程会周期性的将数据发送至远端在N9E monapi端定义告警策略,集成钉钉通知工程结构├── sea-monitor // 监控SDK├── sea-monitor-boot-starter // sp
  • 关于定期报送物业费收费数据通知.doc
  • 包含了事件日志、链路追踪、指标监控能力,同时提供了数据的采集、数据存储以及数据展示三个先对独立的子系统。是一款“广义的”分布式链路追踪系统。 上一篇文章《SkyWalking如何通过修改字节码让插件生效》讲了...

    Skywalking是一款云原生的APM(应用性能管理)系统。包含了事件日志链路追踪指标监控能力,同时提供了数据的采集、数据存储以及数据展示三个先对独立的子系统。是一款“广义的”分布式链路追踪系统。

    在这里插入图片描述

    上一篇文章《SkyWalking如何通过修改字节码让插件生效》讲了SkyWalking的插件工作原理,这篇文章就来探索一下SkyWalking到底是如何实现链路追踪和指标监控的功能的。

    整体工作原理

    在这里插入图片描述

    采集数据过程分析

    链路追踪核心概念:Trace、Span。

    具体在这里不展开,可以自行参考《OpenTracing语义标准》。

    大致如下:
    在这里插入图片描述

    • 一个Trace对应一次完整的调用链路。
    • 一个线程内的调用对应一个TraceSegement。
    • 同一个线程内方法每调用一次就生成一个Span,同时spanId + 1。
    • 跨进程(如服务之间的调用)或跨线程(如异步调用)生成新的TraceSegement和Sapn,并通过指针指向上游链路信息。

    领域建模

    核心领域模型主要分为四个部分:ids、trace、tag、context。

    ids

    在这里插入图片描述
    DistributedTraceId
    org.skywalking.apm.agent.core.context.ids.DistributedTraceId ,分布式链路追踪编号抽象类。
    NewDistributedTraceId
    org.skywalking.apm.agent.core.context.ids.NewDistributedTraceId ,新建 的分布式链路追踪id。
    PropagatedTraceId
    org.skywalking.apm.agent.core.context.ids.PropagatedTraceId,传播 的分布式链路追踪编号,该id并不是重新生成的,而是从上游服务传递过来的。
    例如,A 服务调用 B 服务时,A 服务会将 DistributedTraceId 对象带给 B 服务,B 服务会调用 PropagatedTraceId(String id) 构造方法 ,创建 PropagatedTraceId 对象。

    trace

    在这里插入图片描述
    AbstractSpan
    org.skywalking.apm.agent.core.context.trace.AbstractSpan ,Span 接口。
    NoopSpan
    org.skywalking.apm.agent.core.context.trace.NoopSpan ,实现 AbstractSpan 接口,无操作的 Span,即不会采集数据 。
    配合IgnoredTracerContext使用用于尽可能降低内存和 gc 成本。
    NoopExitSpan
    org.skywalking.apm.agent.core.context.trace.NoopExitSpan,继承 StackBasedTracingSpan 抽象类,无操作的出口 Span 。
    AbstractTracingSpan
    org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan ,实现 AbstractSpan 接口,链路追踪 Span 抽象类。
    StackBasedTracingSpan
    org.skywalking.apm.agent.core.context.trace.StackBasedTracingSpan ,实现 AbstractTracingSpan 抽象类,基于的链路追踪 Span 抽象类。
    LocalSpan
    org.skywalking.apm.agent.core.context.trace.LocalSpan ,继承 AbstractTracingSpan 抽象类,本地 Span ,用于一个普通方法的链路追踪,例如本地方法。
    EntrySpan
    org.skywalking.apm.agent.core.context.trace.EntrySpan ,实现 StackBasedTracingSpan 抽象类,入口 Span ,用于服务提供者( Service Provider ) ,例如 Tomcat 。
    EntrySpan 是 TraceSegment 的第一个 Span ,这也是为什么称为"入口" Span 的原因。
    ExitSpan
    org.skywalking.apm.agent.core.context.trace.ExitSpan ,继承 StackBasedTracingSpan 抽象类,出口 Span ,用于服务消费者( Service Consumer ) ,例如 HttpClient 。
    一个 TraceSegment 会有多个 ExitSpan 对象 ,例如【服务 A】远程调用【服务 B】,然后【服务 A】再次远程调用【服务 B】,或者然后【服务 A】远程调用【服务 C】。
    TraceSegment
    org.skywalking.apm.agent.core.context.trace.TraceSegment ,如上图所示,是一次分布式链路追踪( Distributed Trace ) 的一段。

    tag

    在这里插入图片描述
    AbstractTag
    org.skywalking.apm.agent.core.context.tag.AbstractTag<T> ,标签抽象类。注意,这个类的用途是将标签属性设置到 Span 上,或者说,它是设置 Span 的标签的工具类。
    StringTag
    org.skywalking.apm.agent.core.context.tag.StringTag ,值类型为 String 的标签实现类。
    IntegerTag
    org.skywalking.apm.agent.core.context.tag.IntegerTag ,值类型为 Integer 的标签实现类。
    Tags
    org.skywalking.apm.agent.core.context.tag.Tags ,常用 Tag 枚举类,内部定义了多个 HTTP 、DB 相关的 StringTag 的静态变量。

    context

    在这里插入图片描述
    AbstractTracerContext
    org.skywalking.apm.agent.core.context.AbstractTracerContext ,链路追踪上下文接口。
    TracingContext
    org.skywalking.apm.agent.core.context.TracingContext,实现 AbstractTracerContext 接口,链路追踪上下文实现类。
    与之搭配使用的还有ContextCarrier和ContextSnapshot
    ContextCarrier:org.skywalking.apm.agent.core.context.ContextCarrier,跨进程 Context 传输载体。
    ContextSnapshot:org.skywalking.apm.agent.core.context.ContextSnapshot ,跨线程 Context 传递快照。
    ContextManager
    org.skywalking.apm.agent.core.context.ContextManager,实现了 BootService 、TracingContextListener 、IgnoreTracerContextListener 接口,链路追踪上下文管理器。
    ContextManager 封装了所有 AbstractTracerContext 提供的方法,从而实现,外部调用者,例如 SkyWalking 的插件,只调用 ContextManager 的方法,而不调用 AbstractTracerContext 的方法。

    SK的链路追踪数据的采集过程其实是一个生产者-消费者模型。

    数据生产

    在这里插入图片描述

    1. MethodInterceptor,自定义的插件逻辑(在下面会说)。在执行完插件逻辑,调用后置方法关闭span
    2. TracingContext,链路追踪上下文。从上下文中活跃的 span栈 弹出栈顶那个,将其加入到上下文持有的TraceSegment的已完成span列表中,如何此时活跃的span栈空了,就通知TraceSegment完成监听器IListener。
    3. TraceSegmentServiceClient,实现了IListener接口。监听到TraceSegment完成后,会去调用DataCarrier生产数据。
    4. DataCarrier,数据处理组件。持有QueueBuffer数组,核心逻辑包括生产数据和消费数据,将完成的TraceSegment保存到QueueBuffer里。
    5. QueueBuffer,数据队列。有多个,会根据算法计算TraceSegment对应的index,根据index找到要保存的目标队列。

    数据消费

    在这里插入图片描述

    1. TraceSegmentServiceClient,启动消费服务。
    2. DataCarrier,创建消费者驱动ConsumeDriver,通过消费者驱动来消费消息。
    3. ConsumeDriver,消费者驱。首先给消费者线程分配消费队列QueueBuffer,然后启动消费者线程消费采集到的数据。
    4. ConsumerThread,消费者线程。分配一个列表用来存放当前线程即将消费的数据,把QueueBuffer中的数据放到列表中,执行真正的数据处理逻辑。
    5. TraceSegmentServiceClient,执行真正的数据处理逻辑。将TraceSegment转换为GRPC定义的协议数据(traceId,traceSegmentId,spans等),通过GRPC调用远程接口将采集的数据传递给SK Collector。
    6. SK Collector,SkyWalking服务端的数据收集服务。

    生产-消费全景图

    在这里插入图片描述

    具体插件分析

    上面从抽象的组件角度分析了数据采集上报的过程,下面以一个插件为例看一下在什么时候触发 数据生产 的。

    以常见的Controller方法的处理为例,分析插件RestControllerInstrumentation。
    RestControllerInstrumentation.java

    public class RestControllerInstrumentation extends AbstractControllerInstrumentation {
    
        public static final String ENHANCE_ANNOTATION = "org.springframework.web.bind.annotation.RestController";
    
        @Override
        protected String[] getEnhanceAnnotations() {
            return new String[] {ENHANCE_ANNOTATION};
        }
    }
    

    看到自身并没有核心的逻辑,再看其父类AbstractControllerInstrumentation。
    AbstractControllerInstrumentation.java

    public abstract class AbstractControllerInstrumentation extends AbstractSpring5Instrumentation {
        @Override
        public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
            return new ConstructorInterceptPoint[] {
                new ConstructorInterceptPoint() {
                    @Override
                    public ElementMatcher<MethodDescription> getConstructorMatcher() {
                        return any();
                    }
    
                    @Override
                    public String getConstructorInterceptor() {
                        return "org.apache.skywalking.apm.plugin.spring.mvc.v5.ControllerConstructorInterceptor";
                    }
                }
            };
        }
    
        @Override
        public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
            return new InstanceMethodsInterceptPoint[] {
                new DeclaredInstanceMethodsInterceptPoint() {
                    @Override
                    public ElementMatcher<MethodDescription> getMethodsMatcher() {
                        return byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.RequestMapping"));
                    }
    
                    @Override
                    public String getMethodsInterceptor() {
                        return Constants.REQUEST_MAPPING_METHOD_INTERCEPTOR;
                    }
    
                    @Override
                    public boolean isOverrideArgs() {
                        return false;
                    }
                },
                new DeclaredInstanceMethodsInterceptPoint() {
                    @Override
                    public ElementMatcher<MethodDescription> getMethodsMatcher() {
                        return byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.GetMapping"))
                            .or(byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.PostMapping")))
                            .or(byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.PutMapping")))
                            .or(byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.DeleteMapping")))
                            .or(byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.PatchMapping")));
                    }
    
                    @Override
                    public String getMethodsInterceptor() {
                        return Constants.REST_MAPPING_METHOD_INTERCEPTOR;
                    }
    
                    @Override
                    public boolean isOverrideArgs() {
                        return false;
                    }
                }
            };
        }
    
        @Override
        protected ClassMatch enhanceClass() {
            return ClassAnnotationMatch.byClassAnnotationMatch(getEnhanceAnnotations());
        }
    
        protected abstract String[] getEnhanceAnnotations();
    
    }
    

    看到getInstanceMethodsInterceptPoints方法是不是很熟悉,上一篇文章《SkyWalking如何通过修改字节码让插件生效》里面讲到自定义插件需要继承ClassInstanceMethodsEnhancePluginDefine并重写其getInstanceMethodsInterceptPoints方法。
    事实上AbstractControllerInstrumentation也继承了ClassInstanceMethodsEnhancePluginDefine,说明他其实也是自定义的插件,只不过是SkyWalking内置的。
    既然是插件那就重点看getInstanceMethodsInterceptPoints指定的拦截器RestMappingMethodInterceptor。
    RestMappingMethodInterceptor.java

    public class RestMappingMethodInterceptor extends AbstractMethodInterceptor {
    	@Override
        public String getRequestURL(Method method) {...}
    }
    

    发现本身也没有核心逻辑,继续看其父类AbstractMethodInterceptor。
    AbstractMethodInterceptor.java

    public abstract class AbstractMethodInterceptor implements InstanceMethodsAroundInterceptor {
    
        ...
    
        @Override
        public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
                                 MethodInterceptResult result) throws Throwable {
    
            ...
        }
    
        @Override
        public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
                                  Object ret) throws Throwable {
                try {
                    ...
                } finally {
                    ContextManager.stopSpan();
                }
            }
    
            return ret;
        }
    	...
    }
    

    注意到afterMethod方法的finally语句块里出现了ContextManager.stopSpan();
    而这正是上面分析数据生产的入口!

    总结

    通过这篇文章可以有以下收获:

    Q:如何生产数据?
    A:将采集到的TraceSegment,发送到内存数据队列。
    Q:如何消费数据?
    A:从消费线程内存数据队列拿数据,然后通过GRPC发送到SK Collector。
    Q:什么时候生产数据?
    A:在每个插件定义的逻辑最后会调用ContextManager.stopSpan()来生产数据。

    展开全文
  • 中国人民银行(科技司)印发银科技【2020】37号文件《中国人民银行科技司关于做好金融业科技信息综合管理平台第三批次接入工作的通知》(以下简称《通知》),《通知》基于提升金融业信息化发展规划、金融科技监管等...

    中国人民银行(科技司)印发银科技【2020】37号文件《中国人民银行科技司关于做好金融业科技信息综合管理平台第三批次接入工作的通知》(以下简称《通知》),《通知》基于提升金融业信息化发展规划、金融科技监管等履职方面的宏观决策能力;提高金融机构在信息标准化建设、金融科技发展等方面的管理能力的背景下,人行科技司组建了“金融业科技信息综合管理平台”,平台通过模型与算法,建立量化评价标准,从共享与生态的角度挖掘平台数据价值,推动机构画像的建立,构建穿透式监管体系,现平台已启动第三批接入工作,要求各人民银行各级分支机构和直属企事业及相关单位、全国性银行机构、地方性银行机构,将IT基础设施、基础软件和应用系统等相关数据例行报送。

    上报挑战

    > 采集范围广

    《通知》要求金融机构在规定时间内使用指定接口规范及参数要求报送精细颗粒度的金融元数据共涉及59类IT资产的配置数据和关联关系,2064个属性,涉及全行基础设施元数据的采集,数据基数大,采集难度高。

    在这里插入图片描述

    > 数据合规难

    人行对每个数据元属性及上报接口都有特定的标准,对上报数据核验有严格要求,因此,各行数据梳理工作更为繁重,对数据的准确性、合规性也有更高的要求。

    > 时间要求短

    人行对各接入机构行的的工作计划、环境准备、接入联调、首次上报等工作都有严格的时间节点要求,要求在2021年6月30日前,完成数据首次批量上报。

    > 报送频率高

    根据《通知》要求,此次数据报送是一个长期的持续性工作,并且要求对IT资产变更数据实时上传,实时更新。

    产品方案

    广州云新信息技术有限公司(以下简称“广州云新”)根据人行金融业科技信息综合管理平台信息数据上报接入要求, 独立研发CloudSino人行数据上报平台,平台支持数据自动采集、数据模板采集、数据合规校验、数据智能管理、数据压缩与上报、上报结果查询、变更上报、日志报表等丰富功能,能够最大程度上地减少人工参与,且完全符合各金融接入机构基础数据元不同的报送需求,助力各大银行按时、轻松、高效、精准地完成本次数据上报和维护工作。

    > 数据采集

    CloudSino人行数据上报平台提供“自动采集、第三方系统对接、excel批量导入”三种采集方式,确保数据的完整性和及时性。IT设备数据是人行上报工作中要求颗粒度最深的,细化到CPU的核数、频率等,人工录入数据量大、准确率低,区别于其它厂商,CloudSino人行数据上报平台支持自动采集IT设备信息,涵括服务器、网络设备、存储设备、安全设备、空气调节类、操作系统、应用软件等,解决人工投入大、数据量大、收集整理困难等问题。
    在这里插入图片描述
    (图中蓝色信息为自动采集,灰色字体为手动录入,红底色为不合规数据)

    CloudSino人行数据上报平台支持接入各类第三方平台数据,包括CMDB、安防、动环等系统,实现数据的自动获取,同时对于配电、消防类等无法获取的数据,提供符合人行《通知》规范的数据元采集模板,实现数据批量导入。
    在这里插入图片描述

    > 数据管理

    支持对59类数据元实例进行统一管理,管理目录参照人行发布的数据元分类进行设计,为每一类数据元实例提供单独的管理页面,可以对每条数据进行新增、修改、删除、批量导入等操作。
    在这里插入图片描述
    在这里插入图片描述

    > 数据上报

    CloudSino人行数据上报平台按照内置规范上报接口,点击一键上报即可完成,支持自定义时间段采集和上报数据。
    在这里插入图片描述

    > 数据变更

    自动采集IT设备数据,数据变更时自动同步,用精准的监测数据替代人工录入,保障数据的准确性和及时性。
    在这里插入图片描述

    > 合规校验

    平台内置数据合规性校验,依据人行规范自动进行合规性监测,对上传数据进行数据类型异常、属性实例缺失、属性格式错误、属性实例重复等合规性校验,对异常数据进行告警提示,管理人员可以通过颜色告警快速定位异常数据,并及时修正,保证上报数据的合规性。全面提高上报数据的合规率。
    在这里插入图片描述

    总行-分行统一管理

    平台支持根据银行实际的组织架构进行权限管理,分行、总行使用同一平台进行数据采集和更新维护,分行数据上报总行,总行再将汇总数据上报人行综合管理平台,实现各级数据的高效统一管理。

    CloudSino人行数据上报管理平台优势

    > 高自动化、高精准度、高效率

    平台不仅能帮助各金融接入机构在有限的时间内合规、精准、快速地完成与人行报关平台的的对接和信息报送。云新信息更着眼于未来,利用自身在智能业务运维的产品优势以及在金融运维领域丰富的经验积累,帮助客户提升金融机构的IT资产数据管理规范性和标准化能力,在满足人行监管要求的同时,为企业的数据治理和运维体系建设做出长远规划与布局,帮助企业建设智能业务运维体系,提升数字化竞争力。

    • 满足金融监管合规要求;
    • 自动采集数据能取代人工录入,支持合规校验,保证数据的准确性和规范性;理清资源使用情况,对成本控制提供更好的数据决策支撑;
    • 避免各系统数据重复建设的问题,降低了信息维护成本;
    • 优化监管报送业务流程,并根据相关监管部门最新的制度规范进行同步更新;
    • 上报工作是持续性的,因此,CloudSino人行数据上报平台不仅是上报平台,还是持续性、可扩展使用的运维管理平台;
    • 提供个性化模块选择,包括设备实时巡检、远程管理、保修管理、资产盘点等,所有的系统方案均采用模块化设计,既可按照需求进行组装式定制,也方便了未来的扩展升级,无论监管部门的制度规范如何变化,都能够及时、准确的帮助实现监管报送业务流程的同步升级。

    现平台已全面开放测试体验,如有需要请选择以下方式联系:

    在这里插入图片描述

    展开全文
  • 对于《规范》中已经列出数据项值的数据项,严格依照标准中已有的分类上报。 9. 敏感信息处理:对于客户隐私均在备注栏内做了注解,分为“隐私,暂不取”、“隐私,银行机构变形”两种情况。对于“隐私,暂不取”数据...
  • 当达到3分钟之后,上报数据。 3.3 30分钟随机上报 设备错峰上报,30分钟内随机一个时间点上报,间隔一分钟一个电流点。 随机时间 = (SN_Num % Tmin)*30s + X 其中: Tmin = report.regular_time *2 (report....
  • Android/iOS数据上报框架

    千次阅读 2018-11-23 19:54:05
    Android/iOS数据上报框架 移动平台数据上报是很常见的需求。常见的实现方式是, 1. 创建一个带队列的线程。...1. 上层写入数据过快,写文件线程来不及写入文件,此时应用发生crash或app被杀,导致上报数据丢失。 ...
  • 涂鸦模组数据通信概述涂鸦功能修改压力值上报压力状态上报增值服务最后 概述 涂鸦智能 (NYSE:TUYA) 是一家致力于让生活更智能的领先技术公司,涂鸦提供能够智连万物的云平台,打造互联互通的开发标准,连接品牌、...
  • 国家卫生健康委办公厅关于印发全国医院数据上报管理方案(试行)的通知   国卫办规划函〔2019〕380号 各省、自治区、直辖市及新疆生产建设兵团卫生健康委,委机关各司局,委直属和联系单位: 为加强和规范全国...
  • 九思成数据上报简介

    2014-07-23 21:04:04
    数据上报系统能让普通用户自由建表,能自定义管理流程,能自定义各种统计报表,B/S网络架构,能轻松实现信息共享、协同处理,是信息化的理想选择。
  • 今年6月,国家卫健委发布了《关于启动 2020 年度⼆级...2)数据量极大:首次上报数据量大,以某二级医院为例,2017.01-2020.07 记录达10万+。 3)数据问题多:病案首页数据存在有误或不规范情况,上传校验反馈问题可达
  • 关于做好教育信息化管理系统数据填报的相关工作要求.doc
  • 设计开发了基于云计算的棉花数据服务系统,通过采用.NET技术,B/S架构,SQL server数据库,完成了棉花加工企业-县发改委-地州市发改委-自治区发改委四级棉花数据上报机制,实现了通知公告、数据申报及审核、企业停报...
  • 数据运营平台-数据采集

    千次阅读 2020-11-20 18:29:38
    行为数据采集 业务数据采集与转换 第三方系统API对接 用户数据关联 人工数据采集 数据输出 行为数据采集 1.埋点采集 ①跨平台打通 确定性方法识别 利用用户帐号体系中,可以是系统生成的 UserID,可以是...
  • 阿里云DataWorks数据集成(DataX)架构&实践分享 分享嘉宾:罗海伟阿里云 编辑整理:约理中国科学院大学 目录 阿里云DataWorks数据集成(DataX)架构&实践分享 ▌为什么需要数据集成 数据集成的应用...
  • 系统通过api与企业微信进行对接,可实现系统数据与企业微信上进行数据交互。 本次教程在白码低代码开发平台以订单的提交效果做示例。 效果演示: 审核通过: 审核拒绝: 效果实现: 首先需要系统集成...
  • 国家卫生健康委办公厅于2020年7月发布了“关于进一步加强单病种质量管理与控制工作的通知”(国卫办医函〔2020〕624号),通知要求各医疗机构需将单病种质量管理与控制工作制度作为医疗质量管理制度的重要组成部分,...
  • 订阅上传结果通知 设备可以订阅系统 topic 获取上传数据点结果消息 打开MQTT.fx,连接设备,选择Subscribe项,输入订阅topic名称 topic 命名规则如下: $sys/{pid}/{device-name}/dp/post/json/+ 就比如我的是$...
  • 此数仓项目文档详细介绍从项目需求分析到数据生成模块、数据采集模块、数仓各分层搭建再到业务实现的过程,其中各种环境的配置很细致,很有价值学习一下。
  • 数分面试:如何保证数据准确性?

    千次阅读 2021-08-12 00:28:35
    如何用科学的方法,保障数据准确性|0x00 问题描述我是小z前几天面试问了一个问题:怎么保证数据的正确性?以下是原文:上游,会遇到根源性问题,比如客户端在数据上报时就传错的情况,比如手抖把...
  • 甚至,或许可以这么做:来做一个软件的FIFO,把数据先放到这里,因为电容屏的上报频率一般50HZ就可以下了,所以可以将数据先做个缓冲,缓冲100~200ms的数据就可以了(5~10个点)。然后另起一个线程,以准确的固定频率...
  • 嵌入式开发中其实最重要的就是数据传输,这部分由于频繁的使用,高效的格式和算法就变得很重要,算法这部分会在其他文章单独叙述,这里主要是想说下数据格式 使用过单片机开发的同学应该比较熟悉,可能就是自己...
  • 数据资产治理:元数据采集那点事

    千次阅读 2021-03-31 10:17:45
    ‍‍正文开始一、介绍数据资产治理(详情见:数据资产,赞之治理)的前提要有数据。它要求数据类型全、量大,并尽可能多地覆盖数据流转的各个环节。元数据采集就变得尤其重要,它是数据资产治理的核心底...
  • PBOC相关上报文档

    2016-04-07 17:20:53
    PBOC相关上报文档
  • 介绍Curve的元数据节点MDS,包括: MDS总体介绍。 Topology模块,包括MDS管理的Curve拓扑结构,故障隔离等。 NameServer,用于保存Curve中文件和目录的层级结构以及分配信息等元数据。 Copyset,介绍Curve中Chunk的...
  • 国家卫⽣健康委办公厅发布《关于启动 2020 年度⼆级和三级公⽴医院绩效考核有关工作的通知》(国卫办医函〔2020〕500 号,以下简称《通知》),通知要求各有关医院应当按照《卫生部关于修订病案首页的通知》(卫医政...
  • 学院人才培养工作状态数据采集平台管理办法.docx

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,976
精华内容 9,190
关键字:

关于上报数据的通知