Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

IntelliJ IDEA 2023.1 EAP 3 现已发布,包括了新 UI 增强功能以​​及对 Kubernetes 和 Docker 功能的多项改进。具体更新内容包括:

用户体验

新 UI 中工具窗口的垂直拆分

在新 UI 中引入了拆分工具窗口区域的选项,方便用户进行窗口排列。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

新 UI 的 Compact Mode 

引入了 Compact Mode 以改善用户在小屏幕上使用 IntelliJ IDEA 的新 UI 的体验。由于工具栏和工具窗口标题的高度降低、间距和填充缩小以及图标和按钮缩小,因此提供了一个更统一的外观和感觉。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Docker

合并所有 Docker-compose 容器的日志

Docker-compose 节点的仪表板选项卡现在将来自每个 Docker-compose 容器的日志汇总在一起,并将它们全部显示在一个地方,实时更新。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

支持 Azure Container Registry

现在可以轻松连接到 Azure Container Registry。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Kubernetes

新 Kubernetes 资源弹出窗口中的文件模板

向 File | New menu 添加了一个新操作,以便更轻松地创建新的 Kubernetes 文件。选择 New Kubernetes Resource 选项后,将出现一个弹出窗口,其中包含最流行的资源类型列表,例如 Pod、Deployment、ConfigMap 等。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

创建新 Kubernetes Secret 的操作

引入了一个新对话框来创建 Kubernetes Secrets。要定义新的 Secret,可以手动输入键和值。或者可以指定一个文件,其内容将用作生成的 Secret 的值。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

从集群加载的 Kubernetes 资源的 gutter 中的 Color-coded 更改标记

当你对集群中的资源使用 View YAML 操作并在打开的文件中进行任何更改时,IDE 会在 gutter 中使用 color-coded 标记高亮显示你的所有编辑。这样可以确保在将更改应用回集群之前对资源的所需部分进行了更改。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

此外,使用 Compare with Cluster 图标,你可以打开一个完整的差异视图,该视图将从集群中获取资源的当前版本并将其与本地版本进行比较。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

改进了 kubeconfig 文件的用户体验

改进了使用 kubeconfig 文件的用户体验。现在可以在服务视图中轻松访问 kubeconfig 文件并在编辑器中打开它。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如果你在 IntelliJ IDEA 之外更改 kubeconfig 文件,IDE 将检测到这一点并自动在服务工具窗口中刷新其配置。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

此外,IDE 现在支持 kubeconfig 文件的代码高亮显示和补全。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

能够为 Service view 中的操作分配自定义快捷方式

现在可以在 Service view 中为大多数 Kubernetes 操作分配快捷方式,例如 Forward PortsDelete Resource 和 Describe Resource等。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

其他

Docker debug deprecation Docker 调试弃用

Docker 调试功能已被弃用。要使用 Docker 容器调试应用程序,需改用 Run targets

Cairo 1.17.8 版本已发布,Cairo 是一个开源的图形库,为软件开发者提供了一个基于矢量图形、独立于设备的 API。Cairo 支持输出到一些不同的后端,后端支持包括 X11、Apple Quartz、Win32,以及 PNG、PDF、PostScript、DirectFB 和 SVG 等文件格式。

近年来 Cairo 的开发停滞不前,2018 年底推出了 Cairo 1.16 稳定版,然后就没有了消息。接着就是当前最新的 Cairo 1.17.8 版本,Cairo 1.17.8 修复了各种错误,改进了对 macOS 和 Windows 的支持,支持渲染 COLRv1 字体,删除了 Autotools 构建系统以专注于 Meson。

此外,该版本还删除了 OpenGL/GLES 支持,因为该后端大约十年没有得到维护。

macOS 和 Windows 的支持改进涉及大量错误修复和构建更改,详情可查看更新公告。

cairo 使用 C 语言撰写的,但使用 cairo 时支持许多其他语言,包括有 C++、C#、Java、Python、Perl、Ruby、Scheme、Smalltalk 以及许多种语言,cairo 在 GPL 与 Mozilla Public License 两个开源许可证下发布。

摘要:物联网是现在比较热门的软件领域,众多物联网厂商都有自己的物联网平台,而物联网平台其中一个核心的模块就是Mqtt网关。

本文分享自华为云社区《一文带你掌握物联网mqtt网关搭建背后的技术原理》,作者:张俭。

前言

物联网是现在比较热门的软件领域,众多物联网厂商都有自己的物联网平台,而物联网平台其中一个核心的模块就是Mqtt网关。这篇文章的目的是手把手教大家写书写一个mqtt网关,后端存储支持Kafka/Pulsar,支持mqtt 连接、断链、发送消息、订阅消息。技术选型:

  • Netty java最流行的网络框架
  • netty-codec-mqtt netty的子项目,mqtt编解码插件
  • Pulsar/Kafka 流行的消息中间件作为后端存储

核心pom依赖如下


软件参数设计

软件参数可谓是非常常见,复杂的开源项目,参数甚至可以达到上百个、配置文件长达数千行。我们需要的配置有

MqttServer监听的端口

监听端口的配置即使是写demo也非常必要,常常用在单测试中,由于单测试跑完之后,即使网络服务器关闭,操作系统也不会立即释放端口,所以单测试的时候指定随机端口非常关键,在java中,我们可以通过这样的工具类来获取一个空闲的端口。未配置的话,我们就使用mqtt的默认端口1883。


后端存储配置

我们的mqtt网关是没有可靠的存储能力的,依赖后端的消息中间件来做持久化处理。后端规划支持Pulsar、Kafka两种类型。定义枚举类如下


对应的KafkaProcessorConfig、PulsarProcessorConfig比较简单,包含基础的连接地址即可,如果后续要做性能调优、安全,这块还是会有更多的配置项


启动netty MqttServer

我们通过netty启动一个mqttServer,添加mqtt解码器


MqttserverStarter.java

我们写一个简单的main函数用来启动mqttServer,方便调测


客户端使用eclipse mqtt client进行测试


然后我们先运行MqttServer,再运行MqttClient,发现MqttClient卡住了


这是为什么呢,我们通过抓包发现仅仅只有客户端发送了Mqtt connect信息,服务端并没有响应

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

但是根据mqtt标准协议,发送Connect消息,必须要有ConnAck响应

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

所以我们需要在接收到Connect后,返回connAck消息。我们创建一个MqttHandler,让他继承ChannelInboundHandlerAdapter, 用来接力MqttDecoder解码完成后的消息,这里要重点继承其中的channelRead方法,以及channelInactive方法,用来释放断链时需要释放的资源


然后把这个handler加入到netty的职责链中,放到解码器的后面

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在mqtt handler中插入我们的代码


打印出connectMessage如下


通常,mqtt connect message中会包含qos、用户名、密码等信息,由于我们启动客户端的时候也没有携带用户名和密码,这里获取到的都为null,我们先不校验这些消息,直接给客户端返回connack消息,代表连接成功


我们再运行起Server和Client,随后可以看到已经走过了Connect阶段,进入了publish message过程,接下来我们再实现更多的其他场景

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

附上此阶段的MqttHandler代码


我们当前把所有的逻辑都放在MqttHandler里面,不方便后续的扩展。抽象出一个MqttProcessor接口来处理具体的请求,MqttHandler负责解析MqttMessage的类型并分发。MqttProcess接口设计如下


我们允许这些方法抛出异常,当遇到极难处理的故障时,把mqtt连接断掉(如后端存储故障),等待客户端的重连。

MqttHandler中来调用MqttProcessor,相关MqttHandler代码如下


这里的代码,主要是针对MqttMessage的不同类型,调用MqttProcessor的不同方法,值得一提的有两点

  • 提前判断了一些解码异常,fast fail
  • 全局捕获异常,并进行断链处理

维护MqttSession

维护Mqtt会话的session,主要用来持续跟踪客户端会话信息,跟踪在系统中占用的资源等,考虑到无论是何种后端实现,都需要维护Mqtt的Session,我们构筑一个AbstractMqttProcessor来维护MqttSession


可以看到,这里的AbstractProcessor主要是维护了MqttSessionKey,校验MqttSessionKey,并拦截publish中不支持的Qos2、Failure。同时,也影响了mqtt心跳请求。同样的,我们允许在onPublishonSubscribe中抛出异常。

基于消息队列实现的mqtt网关的基础思想也比较简单,简而言之就是,有publish消息的时候向消息队列中生产消息。有订阅的时候就从消息队列中拉取消息。由此延伸出来,我们可能需要维护每个mqtt topic和producer、consumer的对应关系,因为像kafka、pulsar这些消息中间件的消费者都是区分topic的,片段通用代码如下:


kafka processor实现


处理MqttPublish消息,MqttPublish消息包含如下几个关键参数


其中

  • qos代表这条消息的质量级别,0没有任何保障,1代表至少一次,2代表恰好一次。当前仅支持qos0、qos1
  • topicName就是topic的名称
  • ByteBuffer就是消息的内容

根据topic、qos发送消息,代码如下


处理订阅消息,我们暂时仅根据订阅的topic,创建topic进行消费即可,由于kafka原生客户端建议的消费代码模式如下


我们需要切换到其他线程对consumer进行消息,书写一个KafkaConsumerListenerWrapper的wrapper,转换为listener异步消费模型


在上述的代码中,有一个需要通篇注意的点:日志打印的时候,注意要将关键的信息携带,比如:topic、mqtt username、mqtt clientId等,在写demo的时候没有感觉,但是海量请求下需要定位问题的时候,就知道这些信息的关键之处了。

使用BountInt这个简单的工具类来生成从0~65535的packageId,满足协议的要求

pulsar processor实现

pulsar相比kafka来说,更适合作为mqtt协议的代理。原因有如下几点:

  • pulsar支持百万topic、topic实现更轻量
  • pulsar原生支持listener的消费模式,不需要每个消费者启动一个线程
  • pulsar支持share的消费模式,消费模式更灵活
  • pulsar消费者的subscribe可确保成功创建订阅,相比kafka的消费者没有这样的语义保障

处理publish消息


处理subscribe消息


集成测试

kafka

我们可以通过embedded-kafka-java这个项目来启动用做单测试的kafka broker。通过如下的group引入依赖


我们就可以通过如下的代码启动基于kafka的mqtt broker


kafka端到端测试用例,比较简单,通过mqtt client publish一条消息,然后消费出来


pulsar

我们可以通过embedded-pulsar-java这个项目来启动用做单测试的pulsar broker。通过如下的group引入依赖


我们就可以通过如下的代码启动基于pulsar的mqtt broker


pulsar端到端测试用例,比较简单,通过mqtt client publish一条消息,然后消费出来


性能优化

这里我们简单描述几个性能优化点,像一些调整线程数、buffer大小这类的参数调整就不在这里赘述了,这些需要具体的性能压测来决定参数的设置。

在linux上使用Epoll网络模型


通过Epollo.isAvailable,以及在指定channel类型的时候通过判断group的类型选择对应的channel类型


关闭tcp keepalive

由于mqtt协议本身就有心跳机制,所以可以关闭tcp的keepalive,依赖mqtt协议层的心跳即可,节约海量连接下的性能。配置ChannelOption.SO_KEEPALIVE为false即可


超时时间调短

默认情况下,无论是单测试中mqtt,还是pulsar producer和kafka producer的生产超时时间,都相对较长(一般为30s),如果在内网环境部署,可以将超时时间调整到5s。来避免无意义的超时等待

使用多个KafkaProducer来优化性能

单个KafkaProducer会达到tcp链路带宽的瓶颈,当有海量请求,而延时在kafka生产比较突出的情况下,可以考虑启动多个KafkaProducer。并根据mqtt协议的特点(链路多,单个链路上qps不高),用mqttSessionKey的哈希值来决定使用那个KafkaProducer发送消息

在KafkaProcessorConfig中添加如下配置,生产者个数,默认为1


在初始化的时候,初始化Producer数组,而不是单个Producer


封装一个方法来获取producer


结语

本文的代码均已上传到github。我们这里仅仅只实现了基础的mqtt 连接、发布、订阅功能,甚至不支持暂停、取消订阅。想要实现一个成熟商用的mqtt网关,我们还需要用户隔离、对协议的更多支持、可靠性、可运维、流控、安全等能力。如有商用生产级别的mqtt需求,又无法快速构筑成熟的mqtt网关的,可以选择华为云IoTDA服务提供稳定可靠的mqtt服务,支持海量设备连接上云、设备和云端消息双向通信能力。

 

关注,第一时间了解华为云新鲜技术~

 1、直接docker部署项目: docker run -d --name "open-anpr" -p 56790:8080 divenswu/open-anpr:1.0.0 2、若想禁用swagger: docker run -d --name "open-anpr" -p 56790:8080 -e VISUAL_SWAGGER_ENABLE=false divenswu/open-anpr:1.0.0 3、若想挂载日志目录到本地: docker run -d --name "open-anpr" -p 56790:8080 -v open-anpr/logs:/app/open-anpr/logs divenswu/open-anpr:1.0.0 4、服务访问:  swagger接口文档: http://127.0.0.1:56790/doc.html
 

基于订阅的密码管理器和数字钱包 Dashlane 宣布开源其 Android 和 iOS 应用程序代码,采用 Creative Commons Attribution-NonCommercial 4.0 许可。此举旨在增加其运作的透明度,以及促进更加协作和开放的开发方式。

透明度和信任是我们公司价值观的一部分,我们努力在我们所做的每一件事中体现这些价值观。我们希望对我们的代码库保持透明将增加客户对我们产品的信任。我们还相信一个更加开放的数字世界,开发者可以在其中轻松参与并相互联系。这是我们对这一雄心壮志的贡献,也是朝着这个方向迈出的又一步。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

通过开源,该公司希望收到更多社区关于改进其移动应用代码的反馈,以及网络安全研究人员提供的的安全漏洞报告。Dashlane 有一个 HackerOne 漏洞赏金计划,报告漏洞的用户可获得最高达 5000 美的赏金

开源还可以在内部促使工程团队提高代码质量,提升代码可读性。Dashlane 计划每三个月在 GitHub 更新一次代码快照,但如果相关流程得到相应的增强,更新频率可能还会更加频繁。

值得注意的是,Dashlane 目前还不能接受来自社区的直接贡献。该公司表示未来或将有让外部贡献者可以直接在 GitHub 中提出改进建议的相关规划,但此举还需另一个层次的内部组织。此外,源代码发布仅涉及 Android 和 iOS 的客户端应用程序,因此 macOS 和 Windows 的客户端应用程序仍然是闭源。

Dashlane 承诺将采取更多措施,接下来将开源其 Web 扩展代码库。不过在此之前,其需要先完成一个满足 Google Chrome MV3 要求的迁移工作。

更多详情可查看官方公告。

Asahi Linux “AGX”Gallium3D 驱动程序已将一些补丁合并到Mesa 23.1 ,其中最重要的是合并了了磁盘着色器缓存支持,在对 Apple Silicon M1/M2 图形的开源 OpenGL 支持方面取得进展。

据外媒 Phoronix 介绍,通过开发人员 Rose Hudson 的合并,现在 Asahi Linux 已可以为 Gallium3D 启用着色器磁盘缓存,以便将 GLSL 着色器缓存到磁盘,加快后续游戏加载速度,并避免可能正在编译着色器的 OpenGL 游戏卡顿情况。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

目前 Asahi 的 Gallium3D 仍处于OpenGL 2.x 环境,但随着更多 OpenGL 3.x/4 的支持,此着色器磁盘缓存功能将变得更加重要,它和基于 Rust 的 DRM 内核驱动程序结合在一起,允许在 Linux 上使用 Apple M1/M2 硬件获得高性能的 OpenGL 游戏体验。

但目前 Asahi AGX Mesa 驱动程序仍处于 Linux 内核驱动树外,对于那些想要试用 Asahi AGX Mesa 驱动程序的人来说,则需要等待约三个月后发布的 Mesa 23.1 。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

​如果你这周没刷到类似 “npub1sg6plzptd64u62a878hep2kev88swjh3tw00gjsfl8f237…” 的一串字符,那就说明本期 GitHub Trending 周榜的内容非常适合你。这是前推特创始人多次推荐的去中心的社交网络 App Damus 的个人主页名片,而支撑这个一周就排名到 iOS 应用榜单前十 App,它背后的协议便是 nostr (同名开源项目)。

除了去中心化社交热点之外,本周其他项目同往常一样,是一些比较实用的工具,比如 root Android 的 KernelSU、提高语音识别精度的 WhisperX、协作平台 APITable、类 ChatGPT 的 AI 对话工具 Open-Assistant,以及 K8s 入门到精通的 kubernetes-learning-path。

以下内容摘录自微博@HelloGitHub 的 GitHub Trending 及 Hacker News 热帖(简称 HN 热帖),选项标准: | | ,根据项目 release 时间分类,发布时间不超过 14 day 的项目会标注 ,无该标志则说明项目 release 超过半月。由于本文篇幅有限,还有部分项目未能在本文展示,望周知 🌝

  • 本文目录
    • 1. 本周特推
      • 1.1 协作平台:apitable
      • 1.2 语音识别:whisperX
    • 2. GitHub Trending 周榜
      • 2.1 Windows 包管理:winget-cli
      • 2.2 AI 对话:Open-Assistant
      • 2.3 去中心化协议:nostr
      • 2.4 K8s 学习路径:kubernetes-learning-path
      • 2.5 Android root:KernelSU
    • 3. 往期回顾

1. 本周特推

1.1 协作平台:apitable

主语言:TypeScript、Java

APITable 一个面向 API 的低代码平台,可用来代替 Airtable 来管理日常的协作事项。Airtable 是款协作平台,可以把文本、图片、链接等资源集中起来,来管理日常工作、生活事项。同 Airtable 类似的 APITable 具有以下特性:

  • 实时协作;
  • 自动表单,可自动同步相关字段;
  • API 优先的面板;
  • 不设上限的跨表连接;
  • 强大的行列权限;
  • 支持内嵌,可在你自己的管理系统中嵌入 APITable;

GitHub 地址→https://github.com/apitable/apitable

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

1.2 语音识别:whisperX

主语言:Python

单词级别的语音识别工具,它用 forced alignment 来提高语音识别的时间戳精度。WhisperX 基于 OpenAI 的 Whisper 模型,通过强制对齐方式与语音模型 ASR(比如:wav2vec2.0)来改进了 Whisper 的时间戳精度。

GitHub 地址→https://github.com/m-bain/whisperX

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2. GitHub Trending 周榜

2.1 Windows 包管理:winget-cli

本周 star 增长数:600+主语言:C++、C

Windows 包管理客户端的源码,基于这个仓库你可以安装包管理工具,也可以参与包管理工具的相关开发工作。

GitHub 地址→https://github.com/microsoft/winget-cli

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.2 AI 对话:Open-Assistant

本周 star 增长数:4,800+主语言:Python、TypeScript

基于聊天的 AI 助手,它能理解对话任务、与第三方系统交互,并动态检索信息。

GitHub 地址→https://github.com/LAION-AI/Open-Assistant

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.3 去中心化协议:nostr

本周 star 增长数:1,400+

近期热点的 Twitter 替代品,免审核、去中心的网络社交 App Damus 采用的去中心化协议 nostr。同所有去中心化协议类似,nostr 不依赖任何中心服务器,有加密键和签名来防篡改记录。

GitHub 地址→https://github.com/nostr-protocol/nostr

2.4 K8s 学习路径:kubernetes-learning-path

本周 star 增长数:1,800+

kubernetes-learning-path 提供了从初级到高级的 K8s 学习路径,下图展示了高级 Kubernetes 架构以及外部服务是如何连接到集群的。此外,本周 GitHub 热榜有一个基于 K8s 部署 PaaS / DevOps 的完整演示教程,你也可以 pick 下 https://github.com/ben/k8s_PaaS。

GitHub 地址→https://github.com/techiescamp/kubernetes-learning-path

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.5 Android root:KernelSU

本周 star 增长数:350+主语言:C、Kotlin

一个 Android 上基于内核的 root 方案。特性:

  • 基于内核的 su 和权限管理;
  • 基于 overlayfs 的模块系统;

GitHub 地址→https://github.com/tiann/KernelSU

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

3. 往期回顾

往期回顾:

  • 让人眼前一亮的应用「GitHub 热点速览」
  • 2023 年该学点什么技术?「GitHub 热点速览」

以上为 2023 年第 5 个工作周的 GitHub Trending 🎉如果你 Pick 其他好玩、实用的 GitHub 项目,来 HelloGitHub 和大家一起分享下哟 🌝

作者:京东科技 文涛

 

前言


GC是Garbage Collection的缩写,顾名思义垃圾回收机制,即当需要分配的内存空间不再使用的时候,JVM将调用垃圾回收机制来回收内存空间。

那么JVM的垃圾机制是如何工作的呢?

第一步识别出哪些空间不再使用(识别并标记出哪些对象已死);

第二步回收不再使用空间(清除已死对象 )

判断对象是否已死

判断对象是否已死通常有两种方式 ,引用计数法和可达性分析法

引用计数法

给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不能再被使用的。

简单高效,但无法解决循环引用问题,a=b,b=a

引用计数法并没有在产品级的JVM中得到应用

可达性分析法

这个算法的基本思路就是通过一系列的称为“ GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链( Reference Chain),当一个对象到 GC Roots没有任何引用链相连(用图论的话来说,就是从 GC Roots到这个对象不可达)时,则证明此对象是不可用的。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

不过可达性算法中的对象并不是立即死亡的,对象拥有一次自我拯救的机会,对象被系统宣告死亡至少要经历两次标记过程,第一次是经过可达性分析之后没有与GC Roots相连的引用链,第二次是在由虚拟机自动建立的Finalize队列中判断是否需要执行finalize()方法。

HotSopt虚拟机采用该算法。

清除已死对象的方式

标记清除算法

先标记再清除

不足:1 效率问题,标记和清除效率都不高。2 空间问题,产生大量空间碎片

复制算法

内存分两块,A,B

A用完了,将存活对象拷贝到B,A清理掉

代价:内存少了一半。

HotSopt虚拟机用此算法回收新生代。将新生代内存划分为8:1:1的Eden和Survivor解决复制算法内存使用率低的问题

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

标记整理算法

老年代使用,方式和标记清除类似,只是不直接清除,而是将后续对象向一端移动,并清理掉边界以外的内存。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

分代收集算法

分代收集是一个算法方案,整合了以上算法的优点,一般是把Java堆分为新生代和老年代,在新生代中,使用复制算法老年代“标记一清理”或者“标记一整理”

历代垃圾收集器简介

通过上文我们了解了怎样识别垃圾,怎样清理垃圾,接下来,讲ZGC之前,我们回顾一下历代垃圾回收是怎样做的,主要是想给读者一种历史的视角,任何技术都不是凭空产生的,更多的是在前人成果之上进行优化整合

我们先看一个历代JDK垃圾收集器对比表格,以下表格着重说明或引出几个问题:

1 CMS从来未被当作默认GC,且已废弃

2 CMS的思想其实部分被ZGC吸收,CMS已死,但他的魂还在

3 JDK11、JDK17为长期迭代版本,项目中应优先使用这两个版本

版本
发布时间
默认收集器
事件
jdk1.3
2000-05-08
serial

jdk1.4
2004-02-06
ParNew

jdk1.5/5.0
2004-09-30
Parallel Scavenge/serial
CMS登场
jdk1.6/6.0
2006-12-11
Parallel Scavenge/Parallel Old

dk1.7/7.0
2011-07-28
Parallel Scavenge/Parallel Old
G1登场
jdk1.8/8.0
2014-03-18
Parallel Scavenge/Parallel Old

jdk1.9/9.0
2014-09-8
G1
CMS废弃
jdk10
2018-03-21
G1

jdk11
2018-09-25
G1
ZGC登场
jdk12
2019-3
G1
Shenandoah
jdk13
2019-9
G1

jdk14
2020-3
G1
CMS移除
jdk15
2020-9-15
G1
ZGC、Shenandoah转正
jdk16
2021-3-16
G1

jdk17
2021-09-14
G1
ZGC分代
jdk18
2022-3-22
G1

jdk19
2022-9-22
G1


GC分类

我们经常在各种场景听到以下几种GC名词,Young GC、Old GC、Mixed GC、Full GC、Major GC、Minor GC,他们到底什么意思,本人进行了以下梳理

首先GC分两类,Partial GC(部分回收),Full GC

Partial GC:并不收集整个GC堆的模式,以下全是Partial GC的子集

Young GC:只收集young gen的GC

Old GC:只收集old gen的GC。只有CMS的concurrent collection是这个模式

Mixed GC:只有G1有这个模式,收集整个young gen以及部分old gen的GC。

Minor GC:只有G1有这个模式,收集整个young gen

Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。

Major GC:通常是跟full GC是等价的

serial收集器

单线程收集器,“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。它依然是虚拟机运行在 Client模式下的默认新生代收集器。它也有着优于其他收集器的地方:简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说, Serial I收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。

下图彩色部分说明了它的算法,简单粗暴

1 停止用户线程

2 单线程垃圾回收新生代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

ParNew收集器

Parnew收集器其实就是 Serial l收集器的多线程版本。它是许多运行在 Server模式下的虚拟机中首选的新生代收集器,其中有一个与性能无关但很重要的原因是,除了 Serial 收集器外,目前只有它能与CMS收集器配合工作。Pardew收集器在单CPU的环境中绝对不会有比 Serial收集器更好的效果。它默认开启的收集线程数与CPU的数量相同,在CPU非常多(臂如32个)的环境下,可以使用-XX: ParallelGCThreads参数来限制垃圾收集的线程数。

ParNew收集器追求降低GC时用户线程的停顿时间,适合交互式应用,良好的反应速度提升用户体验.

下图彩色部分说明了它的算法,同样简单粗暴

1 停止用户线程

2 多线程垃圾回收新生代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Parallel Scavenge 收集器

Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器。算法的角度它和ParNew一样,在此就不画图解释了

Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量( Throughput)

吞吐量是指用户线程运行时间占CPU总时间的比例

通过以下两种方式可达到目的:

1.在多CPU环境中使用多条GC线程,从而垃圾回收的时间减少,从而用户线程停顿的时间也减少;

2.实现GC线程与用户线程并发执行。

Serial Old收集器

Serial Old是 Serial 收集器的老年代版本,它同样是一个单线程收集器,使用“标记整理”算法。这个收集器的主要意义也是在于给 Client模式下的虚拟机使用。

如果在 Server模式下,那么它主要还有两大用途:

一种用途是在JDK1.5以及之前的版本中与 ParallelScavenge收集器搭配使用,

另一种用途就是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用

下图彩色部分说明了它的算法,同样简单粗暴

1 停止用户线程

2 单线程垃圾回收老年代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Parallel Old收集器

Paralle Old是 Parallel Scavenge收集器的老年代版本,一般它们搭配使用,追求CPU吞吐量,使用多线程和“标记一整理”算法。

下图彩色部分说明了它的算法,同样简单粗暴

1 停止用户线程

2 多线程垃圾回收老年代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

CMS收集器

以上5种垃圾回收原理不难理解,算法之所以如此简单个人理解在当时使用这种算法就够了,随着JAVA的攻城略地,有一种垃圾回收需求出现,即使用尽量短的回收停顿时间,以避免过久的影响用户线程,CMS登场了。

CMS( Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。

想要达到目的,就要分析GC时最占用时间的是什么操作,比较浪费时间的是标记已死对象、清除对象,那么如果可以和用户线程并发的进行,GC的停顿基本就限制在了标记所花费的时间。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如上图,CMS收集器是基于“标记一清除”法实现的,它的运作过程分为4个步骤


初始标记( EMS initial mark) stop the world

并发标记( CMS concurrent mark)

重新标记( CMS remark) stop the world

并发清除( CMS concurrent sweep)

初始标记的作用是查找GC Roots集合的过程,这个过程处理对象相对较少,速度很快。(为什么要进行初始标记:枚举根结点。https://www.zhihu.com/question/)

并发标记是实际标记所有对象是否已死的过程,比较耗时,所以采用并发的方式。

重新标记主要是处理并发标记期间所产生的新的垃圾。重新标记阶段不需要再重新标记所有对象,只对并发标记阶段改动过的对象做标记即可。

优点:

并发收集、低停顿

缺点:

CMS收集器对CPU资源非常敏感。

CMS收集器无法处理浮动垃圾( Floating Garbage),可能出现“Concurrent ModeFailure”失败而导致另一次 Full GC的产生。

“标记一清除”法导致大量空间碎片产生,以至于老年代还有大量空间,却没有整块空间存储某对象。


G1收集器

G1是一款面向服务端应用的垃圾收集器。下文会简单讲解一下它的“特点”和“内存分配与回收策略”,有基础或不感兴趣的同学直接跳到“G1垃圾回收流程”

特点

并行与并发

G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The- World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。

分代收集

与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。

空间整合

与CMS的“标记一清理”算法不同,G1从整体来看是基于“标记一整理”算法实现的收集器,从局部(两个 Region之间)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。

可预测的停顿

这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。

在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域( Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分 Region(不需要连续)的集合

内存分配与回收策略

对象优先在Eden分配

大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次 Minor[ˈmaɪnə(r)] GC

大对象直接进入老年代

所谓的大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组。大对象对虚拟机的内存分配来说就是一个坏消息(比遇到一个大对象更加坏的消息就是遇到一群“朝生夕灭”的“短命大对象”写程序的时候应当避免),经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来“安置”它们。

长期存活的对象将进入老年代

虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次 Minor GC后仍然存活,并且能被 Survivor容纳的话,将被移动到 Survivor空间中,并且对象年龄设为1。对象在 Survivor区中每“熬过”一次 Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认15岁)会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数据-XX : MaxTenuringThreshold设置

动态对象年龄判定

为了能更好地适应不同程序的内存状况,虚拟机并不是水远地要求对象的年龄必须达到了 MaxTenuringThreshold才能晋升老年代,如果在 Survivor空间中相同年龄所有对象大小的总和大于 Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到 MaxTenuringThreshold中要求的年龄。

空间分配担保

在发生 Minor GC之前,虚拟机会先检査老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么 Minor GC可以确保是安全的。如果不成立,则虚拟机会查看 HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次 Minor GC,尽管这次 Minor GC是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次 Full GC.

为什么要担保:

Minor GC后还有大量对象存活且空间不够存放新对象,就要直接在老年代存放

为什么是历次晋升到老年代对象的平均大小:

取平均值进行比较其实仍然是一种动态概率的手段,也就是说,如果某次 Minor GCd存活后的对象突增,远远高于平均值的话,依然会导致担保失败( HandlePromotionFailure)如果出现了 HandlePromotionFailure失败,那就只好在失败后重新发起一次 Full GC。虽然担保失败时绕的子是最大的,但大部分情况下都还是会将 HandlePromotionFailure开关打开,避免 Full GC过于频繁。

eden的大小范围默认是 =【-XX:G1NewSizePercent,-XX:G1MaxNewSizePercent】=【整堆5%,整堆60%】

humongous如果一个对象的大小已经超过Region大小的50%了,那么就会被放入大对象专门的Region中,这种Region我们叫humongous

G1垃圾回收流程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

网上对G1的回收阶段有不同的说法,参考Oracle JVM工程师的一个说法:

他把整个 G1 的垃圾回收阶段分成了这么三个,第一个叫 Minor GC,就是对新生代的垃圾收集,第二个阶段呢叫 Minor GC + Concurrent Mark,就是新生代的垃圾收集同时呢会执行一些并发的标记,这是第二个阶段,第三个阶段呢它叫 Mixed GC 混合收集,这三个阶段是一个循环的过程。刚开始是这个新生代的垃圾收集,经过一段时间,当老年代的内存超过一个阈值了,它会在新生代垃圾收集的同时进行并发的标记,等这个阶段完成了以后,它会进行一个混合收集,混合收集就是会对新生代、幸存区还有老年代都来进行一个规模较大的一次收集,等内存释放掉了,混合收集结束。这时候伊甸园的内存都被释放掉,它会再次进入新生代的一个垃圾收集过程,那我们先来看看这个新生代的收集 Minor GC。

Minor GC的回收过程(eden满了回收)

选定所有Eden Region放入CSet,使用多线程复制算法将CSet的存活对象复制到Survivor Region或者晋升到Old Region。

下图分7步演示了这个过程

1 初始状态,堆无占用

2 Eden Region满了进行标记

3 将存活对象复制到Survivor Region

4 清理Eden Region

5 Eden Region又满了进行再次标记,此时会连带Survivor Region一起标记

6 将存活对象复制到另一个Survivor Region

7 再次清理Eden Region和被标记过的Survivor Region

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Minor GC结束后自动进行并发标记,为以后可能的Mixed GC做准备

Mixed GC的回收过程(专注垃圾最多的分区)

选定所有Eden Region和全局并发标记计算得到的收益较高的部分Old Region放入CSet,使用多线程复制算法将CSet的存活对象复制到Survivor Region或者晋升到Old Region。

当堆空间的占用率达到一定阈值后会触发Mixed GC(默认45%,由参数决定)

Mixed GC它一定会回收年轻代,并会采集部分老年代的Region进行回收的,所以它是一个“混合”GC。

下图分3步演示了这个过程

1 并发标记所有Region

2 并发复制

3 并发清理



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



ZGC

ZGC(Z Garbage Collector) 是一款性能比 G1 更加优秀的垃圾收集器。ZGC 第一次出现是在 JDK 11 中以实验性的特性引入,这也是 JDK 11 中最大的亮点。在 JDK 15 中 ZGC 不再是实验功能,可以正式投入生产使用了。

目标低延迟


保证最大停顿时间在几毫秒之内,不管你堆多大或者存活的对象有多少。

可以处理 8MB-16TB 的堆

通过以上历代垃圾回收器的讲解,我们大致了解到减少延迟的底层思想不外乎将stop the world进行极限压缩,将能并行的部分全部采用和用户线程并行的方式处理,然而ZGC更”过分”它甚至把一分部垃圾回收的工作交给了用户线程去做,那么它是怎么做到的呢?ZGC的标记和清理工作同CMS、G1大致差不多,仔细看下图的过程,和CMS特别像,这就是我在上文说的CMS其实并没有真正被抛弃,它的部分思想在ZGC 有发扬。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

ZGC 的步骤大致可分为三大阶段分别是标记、转移、重定位。

标记:从根开始标记所有存活对象

转移:选择部分活跃对象转移到新的内存空间上

重定位:因为对象地址变了,所以之前指向老对象的指针都要换到新对象地址上。

并且这三个阶段都是并发的。

初始转移需要扫描 GC Roots 直接引用的对象并进行转移,这个过程需要 STW,STW 时间跟 GC Roots 成正比。

并发转移准备 :分析最有回收价值GC分页(无STW) 初始转移应对初始标记的数据

并发转移应对并发标记的数据

除了标记清理过程继承了CMS和G1的思想,ZGC要做了以下优化

并发清理(转移对象)

在 CMS 和 G1 中都用到了写屏障,而 ZGC 用到了读屏障。

写屏障是在对象引用赋值时候的 AOP,而读屏障是在读取引用时的 AOP。

比如 ,这个过程就会触发读屏障。

也正是用了读屏障,ZGC 可以并发转移对象,而 G1 用的是写屏障,所以转移对象时候只能 STW。

简单的说就是 GC 线程转移对象之后,应用线程读取对象时,可以利用读屏障通过指针上的标志来判断对象是否被转移。

读屏障会对应用程序的性能有一定影响,据测试,对性能的最高影响达到 4%,但提高了 GC 并发能力,降低了 STW。这就是上面所说的ZGC“过分”地将部分垃圾回收工作交给用户线程的原因。

染色指针

染色指针其实就是从 64 位的指针中,拿几位来标识对象此时的情况,分别表示 Marked0、Marked1、Remapped、Finalizable。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

0-41 这 42 位就是正常的地址,所以说 ZGC 最大支持 4TB (理论上可以16TB)的内存,因为就 42 位用来表示地址

也因此 ZGC 不支持 32 位指针,也不支持指针压缩。

其实对象只需要两个状态Marked,Remapped,对象被标记了,对象被重新映射了,为什么会有M0,M1,用来区分本次GC标记和上次GC标记

以下是标记转移算法说明:

1 在垃圾回收开始前:Remapped

2 标记过程:

标记线程访问

发现对象地址视图是 Remapped 这时候将指针标记为 M0

发现对象地址视图是 M0,则说明这个对象是标记开始之后新分配的或者已经标记过的对象,所以无需处理

应用线程

如果创建新对象,则将其地址视图置为 M0

3 标记阶段结束后

ZGC 会使用一个对象活跃表来存储这些对象地址,此时活跃的对象地址视图是 M0

4 并发转移阶段

转移线程:

转移成功后对象地址视图被置为 Remapped(也就是说 GC 线程如果访问到对象,此时对象地址视图是 M0,并且存在或活跃表中,则将其转移,并将地址视图置为 Remapped )

如果在活跃表中,但是地址视图已经是 Remapped 说明已经被转移了,不做处理。

应用线程:

如果创建新对象,地址视图会设为 Remapped

5 下次标记使用M1

M1 标识本次垃圾回收中活跃的对象

M0 是上一次回收被标记的对象,但是没有被转移,且在本次回收中也没有被标记活跃的对象。

下图展示了Marked,Remapped的过程,

初始化时A,B,C三个对象处于Remapped状态

第一次GC,A被转移,B未被转移,C无引用将被回收

第二次GC,由于A被转移过了(Remapped状态),所以被标记M1,此时恰好B为不活跃对象,将被清理

第三次GC,A又被标记成M0

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

多重映射

Marked0、Marked1和Remapped三个视图

ZGC为了能高效、灵活地管理内存,实现了两级内存管理:虚拟内存和物理内存,并且实现了物理内存和虚拟内存的映射关系 在ZGC中这三个空间在同一时间点有且仅有一个空间有效,利用虚拟空间换时间,这三个空间的切换是由垃圾回收的不同阶段触发的,通过限定三个空间在同一时间点有且仅有一个空间有效高效的完成GC过程的并发操作

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

支持NUMA

NUMA是非一致内存访问的缩写 (Non-Uniform Memory Access,NUMA)

早年如下图:SMP架构 (Symmetric Multi-Processor),因为任一个 CPU 对内存的访问速度是一致的,不用考虑不同内存地址之间的差异,所以也称一致内存访问(Uniform Memory Access, UMA )。这个核心越加越多,渐渐的总线和北桥就成为瓶颈,那不能够啊,于是就想了个办法。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



把 CPU 和内存集成到一个单上,这个就是非一致内存访问 (Non-Uniform Memory Access,NUMA)。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



ZGC 对 NUMA 的支持是小分区分配时会优先从本地内存分配,如果本地内存不足则从远程内存分配。

ZGC优劣

综上分析,ZGC在战略上沿用了上几代GC的算法策略,采用并发标记,并发清理的思路,在战术上,通过染色指针、多重映射,读屏障等优化达到更理想的并发清理,通过支持NUMA达到了更快的内存操作。但ZGC同样不是银弹,它也有自身的优缺点,如下

优势:

1、一旦某个Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Region的引用都被修正后才能清理,这使得理论上只要还有一个空闲Region,ZGC就能完成收集。

2、颜色指针可以大幅减少在垃圾收集过程中内存屏障的使用数量,ZGC只使用了读屏障。

3、颜色指针具备强大的扩展性,它可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程相关的数据,以便日后进一步提高性能。

劣势:

1、它能承受的对象分配速率不会太高

ZGC准备要对一个很大的堆做一次完整的并发收集。在这段时间里面,由于应用的对象分配速率很高,将创造大量的新对象,这些新对象很难进入当次收集的标记范围,通常就只能全部当作存活对象来看待——尽管其中绝大部分对象都是朝生夕灭的,这就产生了大量的浮动垃圾。如果这种高速分配持续维持的话,每一次完整的并发收集周期都会很长,回收到的内存空间持续小于期间并发产生的浮动垃圾所占的空间,堆中剩余可腾挪的空间就越来越小了。目前唯一的办法就是尽可能地增加堆容量大小,获得更多喘息的时间。

2、吞吐量低于G1 GC

一般来说,可能会下降5%-15%。对于堆越小,这个效应越明显,堆非常大的时候,比如100G,其他GC可能一次Major或Full GC要几十秒以上,但是对于ZGC不需要那么大暂停。这种细粒度的优化带来的副作用就是,把很多环节其他GC里的STW整体处理,拆碎了,放到了更大时间范围内里去跟业务线程并发执行,甚至会直接让业务线程帮忙做一些GC的操作,从而降低了业务线程的处理能力。

总结

综上,其实ZGC并不是一个凭空冒出的全新垃圾回收,它结合前几代GC的思想,同时在战术上做了优化以达到极限的STW,ZGC的优秀表现有可能会改变未来程序编写方式,站在垃圾收集器的角度,垃圾收集器特别喜欢不可变对象,原有编程方式鉴于内存、GC能力所限使用可变对象来复用对象而不是销毁重建,试想如果有了ZGC的强大回收能力的加持,是不是我们就可以无脑的使用不可变对象进行代码编写

参考:

《深入理解java虚拟机》

《JAVA性能权威指南》

JDK 发展至今的垃圾回收机制

全网最全JDK1~JDK15十一种JVM垃圾收集器的原理总结

为什么CMS需要初始标记?

一步一图带你理清G1垃圾回收流程

美团面试官问我:ZGC 的 Z 是什么意思?

ZGC有什么缺点?

ZGC 原理是什么,它为什么能做到低延时?

本文档示意图原型:https://www.processon.com/view/link/63771dbb3a840c4027

送福利啦!开源中国社区带着30张“开放原子开源基金会OpenHarmony技术峰会”门票正大步走来!

欢迎各位开发者积极报名,我们将筛选出30位报名的开发者送出免费参会资格。

开发者可以得到:

(1)参会门票
(2)自助午餐
(3)活动伴手礼(帆布袋、T恤)
(4)大咖深度面对面

赠送活动报名截止时间2月18日,机不可失时不再来哦!

报名地址:【赠票来啦!】OpenHarmony Tech Summit • 技术峰会 – 活动详情页 – OSCHINA – 中文开源技术交流社区

一、活动简介

开放原子开源基金会OpenHarmony技术峰会,以“技术构筑万物智联”为主题,汇聚学术界、产业界前沿技术,分享当下技术成果,探索下一代技术方向。

本次技术峰会特邀全球开源操作系统技术领袖、前沿实践专家及高校技术导师,面向全球展示OpenHarmony操作系统的技术革新,设置有OpenHarmony高校技术俱乐部、OS内核及视窗、生态与互联、安全及机密计算、编程语言及应用框架、开发者工具6大分论坛,并通过互动展区展示OpenHarmony生态社区的阶段性成果。此外,峰会还将发布OpenHarmony高校技术俱乐部星光计划。

期待更多的伙伴、开发者与贡献者加入OpenHarmony生态社区,共同构筑万物智联的美好世界。

活动官网:OpenAtom OpenHarmony

二、活动时间

2023年2月25日9:00-18:00

三、论坛峰会安排

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

四、演讲嘉宾(待更新)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

五、参与方式

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

六、组织单位

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

写在前面: 面对全面放开后多样的消费机会,开发者们如何在保障品质生活的同时,借助开源工具,全面、科学地规划和管理个人财务,把握资金动向,避开消费陷阱?

LigaAI 特邀我司 Nerd4me 大佬分享其个人财务管理经验,系列共分「概念篇」和「实战篇」。本篇「实战篇」,将展开介绍开发者如何使用 Beancount 系统且便捷地记账。

Beancount 是一个基于纯文本的开源记账软件,提供了一系列开箱即用的命令行工具,以及一套简洁、实用且美观的 Web UI。

其核心记账逻辑是「复式记账法」,即每一笔交易至少关联两个交易账户,一借一贷,数额相等。特别的是, 复式记账法规定「收入为负,支出为正」 —— 在《「钞能力养成指北」前传》中,我们也详细解释了这点,大家可以按需补课。

👉新手指南:Why Beancount?

市面上有非常多成熟、知名的记账工具,为什么我仍强烈推荐使用 Beancount?出于以下几点考虑:

  1. Beancount 采用改良版的复式记账方案,「正负」代替「借贷」 对非会计专业的朋友更友好;

  2. 可直接在本地运行。相比基于云端的工具,数据安全更有保障,无需担心个人账务泄漏;

  3. 纯文本文件管理账目,便于记录和存储。 基于 Beancount 语法生成的文件,很容易阅读;

  4. 提供完整的命令行工具集和可视化工具 (内含大量财报模板),支持基于类 SQL 查询,可轻松生成各种复杂的报表数据;

  5. 账本既是用户的输入文件,也是软件的「数据库」,可实现数据和工具的「无痛搬家」

Beancount 是 Ledger-Like 家族的杰出成员。对比背靠  的 Ledger,基于  的 Beancount 应用轻便,新增插件或二次开发更简单;多货币支持等丰富而强大的功能,能够很好地覆盖各种记账、查账场景。

事实上,Beancount 并不知道什么是「货币」。它只是记录了「通货 Commodity」的变化,而通货完全由用户定义。 因此,Beancount 可以记录含货币在内任何东西的变化,如年假天数、股票、航空里程、信用卡积分……

当然,也可以用来数豆子——这也是「Beancount」名字的由来 >A<

👉 英勇黄铜:基本环境搭建

迈出「Beancount 记账」的第一步,需要安装  环境和对应包。


使用下列命令,生成一个官方提供的示例。


通过  命令运行 Web UI 。默认情况下的 Web UI 会运行在  中。


👉 不屈白银:Beancount 语法入门

环境搭建后,我们需要制作账本来承载账目信息。Beancount 作者在 Beancount User’s Manual 中提供了非常详尽的使用说明,大家可以根据实际需求自行创建。

下面以《「钞能力养成指北」前传》中「老王煎饼摊」为例,逐步演示如何使用 Beancount 编写账本并制成报表。

1. 制作账本

新建一个纯文本文件并保存为 。在任意文本编辑器打开,只需简单两步就能完成账本内容的编写。

第一步:设立交易账户

使用  open  命令设立交易账户,语法结构为。

其中,开户时间应早于该账户关联的首笔交易产生的时间;同时,在复式记账法中,交易账户分为五大类型:

  • Assets – 资产类账户:现金、存款、基金、股票、房子、车子、借出账款等;

  • Liabilities – 负债类账户:信用卡、贷款、花呗、向他人借款等;

  • Income – 收入类账户:工资、奖金、专利、投资收益等;

  • Expenses – 费用类账户:衣食住行等一切花销、过年发出的红包等;

  • Equity – 权益类账户:记账前已有的资产或负债,一般在账户初始化时设置。


第二步:编写交易记录

Beancount 是复式记账工具,其账目分录至少包含三行信息:交易详情、支出详情和收入详情。

交易详情记录了交易时间、收款人信息和交易备注,格式为 。

  • */! 」为对账标识符: * 表示该交易已确认,! 表示该交易存疑/待确认。
  • 双引号中的为选填内容,分别记录「收款人 Payee」和「交易备注 Narration」。

支出/收入详情记录出/进账的账户名称、交易数额和货币类型,出账为负,进账为正,正负金额相加为零。


把「老王煎饼摊」的账本补充完整,就会得到下面这个  文件。


2. 生成财务报表

使用 Beancount 命令行工具集中的  命令,可以实现各类财务报表的自动生成。

比如,  子命令能生成损益表, 可以统计资产负债情况, 用于查询各账户余额等。


账户余额表指出,老王持有 1,000 的固定资产、在食材上花费 400 、煎饼营业收入 1,000 、信用卡欠款 400 。

对许多非技术背景的朋友来说,用命令行呈现的数据有点不太好阅读。没关系,Beancount 自己会出手:Beancount 为我们提供了一个可视化工具 。

安装  后,使用  命令启动 Web UI 服务。在浏览器中打开 ,就可以获得表格式的报表数据。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

👉 荣耀黄金:进阶场景说明

在现实生活中,除了「一对一」交易,我们还会遇到很多涉及多个账户的「一对多」和「多对多」的情况。下面几个场景展示了 Beancount 和复式记账法在处理复杂交易方面的优势。

场景 1 :发工资

应聘谈薪,我们关心「税前工资」和「到手工资」。那么,每月发放的工资、奖金,缴纳的五险一金和个人所得税等费用,在 Beancount 中应该如何入账呢?


不难看出,复式记账法的优势之一是能够清晰地展示同一笔交易中,资金在各个账户之间的流动关系,反映资金运动的来龙去脉。

场景 2 :记录房产

对于房产、车辆等固定资产,我们不只关心其购入时的价值,也同样在乎其后续的升/贬值情况,即当前市场估值

Beancount 不预先定义任何货币,我们可以创建人民币  的变种货币 ,赋予房子一个人民币变种价格(即估值价格)

这样,在以人民币  展示总资产时,我们既能在价格页查看房子的当前市值估值,也不会影响总资产的统计。


场景 3 :AA 制消费分摊

AA 制的费用分摊、信用卡分期还款等交易记账是典型的「一对多」场景。

小红和小明外出吃饭一共花费 500 ,由小红先行支付;小明几天后想起,将 AA 的费用转账还给小红。在小红的账本中,这笔钱应该这样记录:


场景 4 :货币转换

出入境限制全面放开,许多好友也都选择出国游玩散心。在消费记账时,Beancount 如何处理不同货币之间的汇率转化关系?

在登记交易时,使用  即可连接两种互相转换的货币。本例中,信用卡支出的 650 人民币正是由 100 美转换而来。


场景 5 :使用 DSL 进行复杂查询

除了  命令外,Beancount 还提供  工具,支持  语句查询,以满足更复杂的数据统计。感兴趣的朋友可以在 Beancount – Query Language 文档中了解。

这里分享一下让 Beancount 回答「我都在哪些加油站加过几次油」的操作指令。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

👉 超凡大师:最佳实践分享

看到这里的朋友们,恭喜你们已经学会了 Beancount 复式记账的常用语法和操作。它们可以满足生活中绝大多数消费和交易的记账需求。下面分享的是一些个人实践的经验总结,希望能更好地帮你开启「Beancount 之旅」。

1. 账本编辑器的选择

我选择  作为账本文件编辑器,搭配  插件一起使用,可以自动为  或者  文件加上语法高亮、补全账户名,还可以实现金额数据的自动对齐。

具体的配置操作请查看作者在  上提供的帮助文档了解。

2. 账户开户日期的设立

前面提到,交易账户的开设日期应早于该账户首笔交易产生的时间。这里也补充一些比较有意思的开户事件,供诸位参考。

  • Expenses 账户可以使用自己的出生日期作为开户日期;
  • Income 账户可以按来源分类后再选择日期,如  的开户时间是该公司的入职日期;
  • Assets 和 Liabilities 账户中的借/贷记卡的开设日期,与银行的开户日期保持一致。

3. 分割账本文件结构

记账是一个长期习惯,但是随着时间累积,账本文件越变越大,只在一个文件中编写和记录就会变得极其不便。

因此,在创建账本时,我们可以提前规划账本分类,使用 Beancount 的  语法对账本进行结构分割。这样就可以在一个 Beancount 文件中包含其他的文件,就像下面这样:


4. 定期对账

账本的定期对账(或称定期断言,Balance Assertion)就像写代码时的「Ctrl + S」或「Command + S」,无事发生自动隐形,关键时刻出手「救命」。

断言就是告诉 Beancount,在某个日期前,这个账户有多少余额(设值为 A) 。如果 Beancount 计算的该时间点前的交易余额 B,与余额 A 不相等,那它就会报错。此时,我们只需检查两次断言日期之间的交易,就能快速定位错账。

使用  命令标记某个日期前的账户余额(区分  命令中的  子命令),让 Beancount 自动核对账本中的账户余额是否与实际金额相等。


需要注意,断言声明的是所给日期开始前的余额,即当日的交易不算在内。也就是说,上面的断言表示,在 2023 年旦前,即截止至 2022 年 12 月 31 日,工商银行储蓄账户余额为 10,000 。

👉后记

在 wzyboy 的《Beancount——命令行复式簿记》一文中,我第一次了解到「记账神器 Beancount」;2022 年 9  月前后,我正式使用 Beancount 管理个人财务。如今睡前打开  记录当天的资金变动,已经成为固定活动,而在每日的记账、查账中,我也获益良多。

本文分享的 Beancount 入门级操作指令,可以满足(个人)日常记账的简单需求;Beancount 还有许多证券投资、基金净值更新等高级应用,大家可以自行挖宝~

新的一年,坚持记账,搞钱发财!


编者语:# 编程之外 是 LigaAI 开设的全新栏目。在这里,我们将与开发者朋友们一起发现和分享生活中的「技术时刻」,并通过极具创意与实用的「生活代码」,感受「技术改善生活」的真谛。如果你也对「代码提升幸福感」感兴趣,欢迎关注 LigaAI@oschina。

LigaAI 是新一代智能研发协作平台,我们关注研发协作与效率,重视开发者个人的价值创造。往期文章中,我们分享了许多敏捷开发、项目管理、个人成长与提升的文章,欢迎朋友们阅读交流。

体验新一代智能研发协作,请 这里 展开了解。LigaAI 助力开发者扬帆远航,期待与你一路同行!

作者:京东零售 秦浩然

引子

举个栗子,众所周知,我们是可以在京东上购买机票的。 但机票是航司提供的,我们本质上是代理销售而已。

那为什么航司要让我们代理销售呢?

我们又是如帮他做代理的呢?

别急,本文将展开说说他们之间的关系。。。

一个有梦想的航司

从前有个航司打算开展线上销售机票业务,于是设计了如下系统。系统完成后,业务正常开展了。。。

航司销售机票的接口:


航司销售机票的接口实现类:


测试:


测试结果:


业务蒸蒸日上,问题接踵而至

随着业务发展的越来越好,新的问题出现了。

黄牛天天爬接口,系统风险出现了;卖完票没有统计结果,卖成啥样也不知道。

于是航司想增加售前风控、售后统计。加上这些功能后,业务又继续稳步发展了。。。

航司销售机票的接口:


航司销售机票的接口实现类:


测试:


测试结果:


人员捉襟见肘,业务被迫拆分

后来航司发现,就这么点人,又想做风控,又想卖机票,又想做统计,根本忙不过来。

那怎么解决呢? 航司只想专心卖票,不想做这些跟卖票无关的工作,那只能找个代理公司了。

于是,航司找到了JD代替自己做这些工作,自己就负责专心卖票。。。

航司销售机票的接口:


航司销售机票的接口实现类:


JD平台代理航司销售机票实现类:


测试:


测试结果:


朴素的一对一合作方式,静态代理

以上流程对与航司而言,由JD帮助自己关注风控、统计,自已可以专心的卖票,看着很好的样子。

但是JD平台只能给航司卖票,其余的也干不了,航司与JD的关系属于静态绑定的关系,即:被代理类与代理类属于静态绑定的关系,称之为“静态代理”。

据此,我们可以给代理模式下个定义:


保险出现,代理公司高瞻远瞩

某天,保险公司也被风控、统计逻辑搞的焦头烂额,听说航司找了个代理,于是也找到了JD,让JD给他们做代理。

JD想:总不能谁来找我,我就给谁做一套代理系统吧,那我得做多少套,反正他们都是找我做风控、统计的,那我能不能做一套系统,给他们所有的人用呢,说干就干。。。

保险公司销售保险的接口:


保险公司销售保险的接口实现类:


JD平台代理的风控、统计实现类:


测试:


测试结果:


进阶的一对多合作方式,动态代理

到这里航司、保险公司都找到了自己的代理,JD平台也完成了风控、统计代理平台的搭建。再有人来找自己,JD平台都可以满足代理需求,现在看来,已经很完美了。

被代理的商家与JD属于动态绑定的关系,即:被代理类与代理类属于动态绑定的关系,称之为“动态代理”,由于此代理功能依赖JDK提供的Proxy、InvocationHandler类,也成为“JDK动态代理”。

据此,我们可以补充代理模式的定义:


酒店出现,代理公司意外降临

平静的日子没过多久,一天某酒店找来了,要求给他们做代理,做就做呗。轻车又熟路。。。

酒店销售房间:


测试:


测试结果:


怎么回事,平台不好用了!代理公司闭关修炼,查一下问题。。。

优秀代理公司的自我修养

以前给别人代理都好使,这次给酒店代理为何就不行了呢? 一个优秀的代理,有问题就要解决问题。。。

先看异常,代理类不能被强转为目标类型,但是为何之前的都好使?

思考:只有生成的代理类属于目标类型,才能强转,那就需要代理类实现目标类的接口,那问题就可能是这样了,验证一下。

原理分析:JDK代理对象是如何实现的?

让我们先看下源码:


上面分析一堆,那我们来了看看得到的代理类到底是啥,为啥他就能执行那个我们的目标类的方法。同时,还得目标类实现接口?


将我们的字节码文件在此反编译:http://javare.cn,得到我们的代理类:


到此为止真相大白了,原来代理类继承了Proxy父类,同时实现了目标类的接口,这就将我们的目标方法与定义的事件处理器联系起来了。

同时,由于java的单继承模式,导致了代理类只能继承Proxy类,那这样的话,就只好通过目标类的接口来关联目标类了。

小结:JDK动态代理

据此,我们可以再次补充代理模式的定义:


好的合作伙伴就是不抛弃不放弃

到这里,问题是搞明白了,就是酒店的问题,但是好的合作伙伴就是应该不抛弃,不放弃。

酒店跟我们合作,我们就要帮助他们解决困难。那怎么办呢?酒店没接口,JDK代理又非要接口,那我们就不用JDK代理了!

这时,基于类的代理方式就应运而生了—— cglib为我们提供了基于类的动态代理模式。

导Jar包:cglib-3.2.5.jar(cglib核心包)、asm-3.3.1.jar(字节码处理框架)


测试


测试结果


原理分析:cglib代理对象是如何实现的?

那为啥cglib就不用目标类实现接口了呢?让我们看看代理类。


反编译结果


到此,我们知道cglib代理是帮我们新建了一个代理类,此代理类继承自目标类获取目标方法,同时重写了目标方法。

再通过我们定义的拦截器调用我们的目标方法,以此来达到代理目标方法的目的。

总结:JDK、cglib动态代理

据此,我们可以总结代理模式的定义:


代理模式的使用场景

我们知道,Spring的AOP就是依赖于动态代理模式实现的,那我们在日常的开发中有哪些地方能用到代理呢?

•事物

•日志

•监控

•统计

•鉴权

•限流

•缓存

•环境隔离

作者:京东物流 李振 康睿 刘斌 王北永

、 规则引擎业务应用背景

业务逻辑中经常会有一些冗长的判断,需要写特别多的if else,或者一些判断逻辑需要经常修改。这部分逻辑如果以java代码来实现,会面临代码规模控制不住,经常需要修改逻辑上线等多个弊端。这时候我们就需要集成规则引擎对这些判断进行线上化的管理

二、规则引擎选型

目前开源的规则引擎也比较多,根据原有项目依赖以及短暂接触过的规则引擎,我们着重了解了一下几个

drools:

-社区活跃,持续更新

-使用广泛

-复杂

-学习成本较高

https://github.com/kiegroup/drools

easy-rule:

-简单易学

-满足使用诉求

-长时间未发布新版

https://github.com/j-easy/easy-rules

easycode:

-京东物流同事维护的平台

-基于flowable dmn实现

-配置简单直观

-已有大量系统使用

总结:

  1. 简单配置型规则可以接入easycode,平台提供配置页面,通过jsf交互。

<!—->

  1. 复杂规则,需要动态生成规则,easycode目前还不支持。drools从流行度及活跃度考虑,都比easy-rule强,所以选择drools。

三、 drools简单示例

3.1 引入依赖


3.2 写drl文件

我们写一个简单的demo

规则为:

匹配一个sku对象

0<价格<=100 10积分

100<价格<=1000 100积分

1000<价格<=10000 1000积分

在resources文件夹下新增 rules/skupoints.drl 文件 内容如下


3.3 使用起来


3.4 输出

21.png

22.png

3.5 总结

如上,我们简单使用drools,仅需要注意drl文件语法。根据drl文件生成规则的工作内存,通过或者与工作内存交互。整个流程并不复杂。注意 仅是在演示中简单使用,demo中包含使用bean来管理容器的方式,即便在简单使用场景也不应通过 来重复加载规则。

但是这样并不能满足我们线上化判断,或者频繁更改规则的诉求。于是我们在实践中需要对drools更高阶的使用方式。

四、 drools动态化实践

从以上简单demo中我们可以看出,规则依赖drl文件存在。而业务实际使用中,需要动态对规则进行修改,无法直接使用drl文件。

以下是我了解过的四种动态的方案:

  • drt文件,创建模板,动态生成drl文件,也是我们目前所用的方式。

<!—->

  • excel文件导入,实际上和模板文件类似,依然无法直接交给业务人员来使用。

<!—->

  • 自己拼装String,动态生成drl文件,网上大多数博文使用方式,过于原始。

<!—->

  • api方式,drools的api方式复杂,使用需要对drl文件有足够的了解。

最后介绍以下drools在项目中的实际使用方式

4.1 配置规则

我们的业务场景可以理解为多个缓冲池构成的一个网状结构。

示例如下:

23.png

上图中每个方块为一个缓冲池,每条连线为一条从A缓冲池流向B缓冲池的规则。实际场景中缓冲池有数百个,绝大多数都有自己的规则,这些规则构成一张复杂的网络。基于业务诉求,缓冲池的流向规则需要经常变动,我们需要在业务中能动态改变这些连线的条件,或者改变连线。在这种情况下,如果使用静态的drl文件来实现这些规则,需要数百规则文件,维护量大,且每次修改后使规则生效的代价较大。在此背景下,我们尝试drools高阶应用,既规则动态化实践。

我们在创建缓冲池的页面中加入了流向规则的创建环节。每个缓冲池维护自己的流向规则,即为自己的一根连线。如下图:

24.png

4.2 动态生成drl

drt文件内容:

(实际业务模板中比这个复杂,有一定校验及业务逻辑,此处做了简化)


生成drl内容: 根据一个队列及模板的路径进行drl内容的生成


4.3 加载drl

上边的简单示例中,我们使用了 来加载规则文件至工作内存中。实际上我们不可能在每次匹配中重新加载所有规则文件,所以我们可以单例的使用规则容器,通过以下方式或者也可以使用等方式来管理容器。


通过将内容写入 然后重新加载整个 即可重新加载规则,但是这种行为比较重,代价较大

也可以通过 新增一个文件来进行加载,代价小,但是同步各个实例的代价较大。


4.4 匹配

通过 与规则引擎交互


如果使用 则需要在使用完成后进行关闭


在执行规则的过程中可以加入各种监听器对过程中各种变化进行监听。篇幅原因交给各位去探索。

五、 总结

从上边的流程中我们体验了动态规则的创建以及使用。动态规则满足了我们规则动态变化,规则统一管理的诉求。

我也总结了在这种使用方式下drools的几个优缺点。

优点:

  • 规则动态化方便

  • 在工作内存中匹配规则性能好

  • 几乎可以满足所有的规则需求

  • 内置方法丰富完善

缺点:

  • 分布式一致性需要自行处理

  • 需要研发了解drl语法

  • 学习曲线陡峭

  • 匹配过程监控手段需要自行实现

新年快乐,兔飞猛进! 根据最近 CNCF 对2000多名 IT 专业人士的 2022 年度调查,WebAssembly 将成为云原生技术栈的一个关键部分。 该调查主要发现

容器是新常态,而WebAssembly是未来的趋势。

WasmEdge 项目是一个开源的 WebAssembly 运行时,为云原生应用场景进行了优化。已经与 Docker Desktop 和 Fedora / Red Hat Linux 集成并分发。通过带薪的 LFX / CNCF 实习计划为 WasmEdge 做出贡献,为你的简历和技能加上闪亮一笔!

通过 LFX Mentorship 计划为像 WasmEdge 这样的CNCF托管的项目做贡献,你将获得:

  • 丰厚报酬。金额从3000美到6600美不等,取决于你的所在地区
  • 通过一对一的指导学习新的开发技能。如果你被选中,将分配到一个来自 WasmEdge 项目的经验丰富的 Mentor。
  • 有机会获得顶级软件公司的工作机会
  • 加入繁荣的开源社区,获得自豪感和成就感

现在就申请加入 WasmEdge 的 LFX Mentorship 计划,在开源领域做出成绩,并获得从3000到6600美不等的报酬!

WasmEdge 简介

WasmEdge 是一个WebAssembly 运行时,特别为服务器端和云原生应用优化。它提供了许多独特的功能,对云计算至关重要。例如,支持

  • 完整的 WebAssembly 规范,以及新兴的规范,如线程、GC 和组件模型。
  • Advanced networking 如 HTTP/S 客户端和服务器,数据库连接,消息队列连接。
  • 基于流行框架的AI推理,如 Tensorflow,OpenVino,PyTorch
  • 高级语言应用,包括 JavaScript、Python、PHP和 Ruby。开发者可以运行完整的node.js应用程序。
  • 多种 APIs 用 Rust, Go,C/C++, JavaScript 创建 Wasm 应用。
  • 多种 SDKs,将 WasmEdge 嵌入到现有的以其他语言编写的应用程序。

此外,WasmEdge 提供了一个灵活的插件架构 允许开发者为其添加更多功能,并通过广泛的开源合作伙伴充分发掘众多集成和分发渠道。通过我们的技术亮点发现 WasmEdge 的全部潜力。

WasmEdge 得到了云原生生态中主要开发者工具和部署平台的支持。例如,WasmEdge 与 Docker Desktop 集成并分发,覆盖超过 1000 万开发者。 Fedora、Red Hat Linux 和 OpenShift 容器平台上的默认 WebAssembly 运行时。

加入我们,共建云原生技术栈的未来!

LFX Mentorship 项目 (2023 年 3 月至 5 月)

这次我们有四个 mentee 空缺。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

为了更好地协作,每个申请者需先完成预测试,本次预测试的截止时间是2月20日。

1. Stream data processing with WasmEdge

这个项目中,你将使用 WasmEdge Rust SDK 将 WasmEdge 嵌入到用 Rust 编写的 Fluvio 项目中。这是两个很棒的开源项目之间的合作。我们寻找的 mentee 需了解 Rust 和 WebAssembly Rust SDK 。

详情 | 预测试 | 申请链接

2. A Rust library crate for mediapipe models for WasmEdge NN

AI 训练和推理等计算密集型任务始终适用于 Rust 和 WebAssembly。WasmEdge 希望构建一个 Rust 库 crate,从而在 WasmEdge 应用程序中轻松集成 Mediapipe 模型。在这个项目中,你应该为Mediapipe的每个模型建立至少一套库函数。每个库函数都接受一个 media 对象并返回推理结果。我们寻找的 mentee 需要有 Rust 知识和一些机器学习经验。

详情 | 预测试 | 申请链接

3. WasmEdge C++ SDK

这个项目中,你将帮助添加基于 WasmEdge C API的 WasmEdge C++ SDK。WasmEdge C++ SDK 让开发者能轻松地将 WasmEdge 嵌入到他们的 C++ host app 里。我们寻找的 mentee 需要有 C++ 和 WebAssembly 的知识。

详情 | 预测试 | 申请链接

4. Unified WasmEdge tools

命令行是开发软件最常用的工具,WasmEdge 提供了两个工具供开发者使用: 和 。可是提供太多的工具会导致使用起来比较麻烦。因此在本项目中,你需要使用 帮助统一 WasmEdge 工具。这项工作将影响所有 WasmEdge 用户。他们将使用你开发的命令行来运行 Wasm 应用程序。我们寻找的 mentee 需要有 C++ 和 WebAssembly 的知识。

详情 | 预测试 | 申请链接

下一步是遵循mentee 指南,在2023年2月14日前完成申请并在2月20日前完成 pretest。 期待你的加入!

如有问题可公众号后台留言或者加入我们的 Discord。 同时,可以加入2月7日的 WasmEdge 社区会议,议题之一是 LXF mentorship 答疑。

延伸阅读

  1. 了解 sonder-joker’s journey on WasmEdge LFX mentorship
  2. 了解 gusye1234’s journey on WasmEdge LFX mentorship

目录

10.1  openGauss全量备份技术

10.1.1  gs_basebackup备份工具

10.1.2  gs_basebackup备份交互流程


 

本文主要介绍openGauss的备份恢复原理和技术。备份恢复是数据库日常维护的一个例行活动,通过把数据库数据备份到另外一个地方,可以抵御介质类的损坏,增加数据库数据的可靠性。数据库的备份恢复主要分为逻辑备份恢复和物理备份恢复。

逻辑备份是把数据库中的数据导出为文本文件,这些文本文件内容一般来说是SQL语句。恢复数据时再把文本文件中的SQL语句导入数据库中恢复。逻辑备份比较灵活,可以支持库级、模式级和表级备份,但逻辑备份只读取了某个时间点的数据库快照对应的数据,很难实现增量备份,恢复时也无法恢复到指定的时间点。在openGauss中实现逻辑备份恢复的工具为gs_dump/gs_restore,具体使用方法参考openGauss官网《管理员指南》手册。

物理备份是直接复制数据库的物理文件,性能比较高,对应用的约束比较少,但只能对整个库进行备份。物理备份又分为全量备份和增量备份。增量备份又有两种方式,一种是结合数据库的脏页跟踪实现的增量备份,另外一种是根据redo日志的增量实现的增量备份。根据脏页进行的增量备份可以和历史上的备份进行合并,减少存储空间的占用,恢复时可以恢复到增量备份的时间点,无法恢复到任意时间点。根据redo日志进行的增量备份在恢复时可以恢复到指定时间点,但所有的redo日志都需要进行备份,占用的存储空间较大。

逻辑备份主要用于异构数据库的迁移,物理备份主要用于保障数据库数据的可靠性。本章主要介绍openGauss的物理备份机制,包括全量备份技术和增量备份技术。

10.1  openGauss全量备份技术

openGauss有两个备份工具gs_basebackup和gs_probackup。gs_basebackup只能进行全量备份,gs_probackup既可进行全量备份,也可进行增量备份。gs_probackup全量备份的原理和gs_basebackup是类似的,本节以gs_basebackup工具为例介绍全量备份的原理。

10.1.1  gs_basebackup备份工具

gs_basebackup是一个独立的二进制程序,有自己的主函数,代码在src/bin/pg_basebackup目录下。在备份时,gs_basebackup通过指定的IP地址连接openGauss数据库服务器,openGauss数据库服务器把需要备份的数据文件和redo日志文件发送给备份工具gs_basebackup,gs_basebackup收到后把文件存放到本地指定的目录,从而完成数据库的备份。

gs_basebackup主要有两种备份格式:plain普通格式和tar压缩包格式。普通格式就是以通常的数据文件进行备份,tar压缩包格式就是把备份文件打包进行备份。openGauss的tar包头是2048字节,文件名最长支持1024个字节长度,不是标准的tar,所以需要openGauss自己解包,实现解包的命令为GsTar。

gs_basebackup的主干处理流程比较简单,首先对支持的命令行参数进行解析,主要的命令行参数请参照表1。参数解析后进入备份主函数BaseBackup,BaseBackup参照后面详细介绍。在主函数之后是free_basebackup,释放前面分配的内存资源,整个备份流程就结束了。

表1  命令参数

参数

描述

-D

备份的目的路径

-F

备份的文件格式,plain普通格式和tar压缩包格式

-X

是否进行流复制模式,当前要求必须采用流复制模式,保证备份数据的正确性

-Z

压缩级别

-c

备份时是否做快速检查点

-h

进行备份的数据库服务器监听IP地址

-p

进行备份的数据库服务器监听端口号

-U

进行备份时连接数据库服务器的用户名

-W

进行备份时连接数据库服务器的密码

-s

备份时状态更新时间间隔

-v

是否显示备份详细信息

– P

是否显示备份进度信息

10.1.2  gs_basebackup备份交互流程

1. plain普通格式备份

普通格式备份的主函数为BaseBackup,具体交互流程如图1所示。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图1 备份交互流程

从图1可以看出,数据库物理全量备份主要包括两个流程,一个是数据文件的备份,一个是XLOG文件的备份。详细过程如下。

(1) gs_basebackup在BaseBackup函数中创建数据传输的连接。

(2) 执行IDENTIFY_SYSTEM命令,获取时间线和系统标识符。

(3) 执行BASE_BACKUP LABEL备份命令,获取XLOG的存放路径和备份开始时日志的位置。然后从数据库服务器获取表空间的路径,创建对应的路径。

(4) 在拷贝数据文件之前,创建一个单独的子进程用于日志传输。日志传输处理的主函数为StartLogStreamer,在StartLogStreamer函数中,先调用GetConnection函数创建一个日志传输的连接,然后调用fork函数创建子进程,在子进程内部通过LogStreamerMain函数调用ReceiveXlogStream执行实际的日志传输。在ReceiveXlogStream中,也是先调用IDENTIFY_SYSTEM获取系统标识并且进行校验和前面获取的系统标识是否一致。接着执行START_REPLICATION,通知数据库服务器日志传输的起始位置。调用createHeartbeatTimer启动心跳线程,保证能够实时监控传输过程中的连接状态。接下来进行日志接收循环,接收数据库服务器传输的日志,写入本地日志路径,直到接收到通知的日志停止位置。

(5) 在主进程创建日志接收子进程之后,调用ReceiveAndUnpackTarFile进行数据文件的拷贝,在这个函数中,有一个while (1)循环,循环接收数据库服务器传输的数据文件,直到接收完数据库服务传输的全部数据文件。数据库文件传输完毕后,数据库服务器会返回一个备份结束时的日志位置。

(6) 主进程接收这个位置,把这个位置通过管道发送给日志接收子进程,日志接收子进程把这个位置与当前日志传输位置相比较,如果达到了这个位置,则日志接收结束,日志子进程退出。主进程等到日志传输子进程退出后,数据库备份的主流程就基本结束了。这个过程保证了redo日志覆盖到整个数据库文件的复制过程,即使在复制数据文件时可能由于数据库的并发刷盘导致数据页可能不一致,但这些不一致可以通过redo日志进行恢复,从而保证整个数据库备份数据的一致性。

(7) 后面两个函数,一个是FetchMotCheckpoint函数,这个函数备份MOT内存表的数据文件,流程和前面基本相似;还有一个是backup_dw_file函数,在backup_dw_file文件中,删除存在的双写文件,然后写入一个空的数据页,这个只是一个空文件,避免启动时的文件检查异常。最后释放前面获得的系统标识符,至此,客户端工具完成整个备份流程。

在数据库服务器端,备份主要在HandleWalReplicationCommand函数中进行,该函数主要接收客户端命令,并根据命令标识符进行处理。

(1) IDENTIFY_SYSTEM命令对应的标识符为T_IdentifySystemCmd,处理函数为IdentifySystem,在IdentifySystem中,构造systemid和timeline的数据组,返回给客户端备份工具。

(2) BASE_BACKUP LABEL命令对应的标识符为T_BaseBackupCmd,对应的主要处理函数为SendBaseBackup,在SendBaseBackup函数中,首先调用parse_basebackup_options解析备份的命令参数,包括备份标签(label)、备份进度(progress)、快速检查点(fast)、是否等待(nowait)、是否包括redo日志(wal)等选项参数,最后调用send_xlog_location函数发送日志文件的路径,接着调用perform_base_backup函数执行数据文件的备份。在perform_base_backup函数中,首先调用do_pg_start_backup执行备份权限检查,根据备份命令行参数决定是否请求检查点(RequestCheckpoint函数),然后生成备份标签文件backup_label,backup_label是备份的重要文件,这个文件包括的内容如下。

① START WAL LOCATION:备份开始时日志的位置。

② CHECKPOINT LOCATION:检查点的位置。

③ BACKUP METHOD:备份方法,pg_start_backup方式还是streamed方式。pg_start_backup没有指定备份标签文件,整个数据库只能同时运行一个备份。streamed方式有备份标签文件,可以同时运行多个备份。

④ BACKUP FROM:备份源standby还是master。

⑤ START TIME:备份开始的物理时间。

⑥ LABEL:备份标签。

backup_label文件最重要的作用是记录数据库恢复的起始位置,在数据库恢复时使用,其次是对本次备份的一个标识及记录一些备份的参考信息。

最后调用SendXlogRecPtrResult函数把备份开始时的日志位置发送给客户端。

perform_base_backup函数在/* Collect information about all tablespaces */while ((de = ReadDir(tblspcdir, “pg_tblspc”)) != NULL) 循环读取每个表空间的数据文件,通过sendTablespace调用sendDir,把表空间目录下的数据文件发送给客户端备份工具。在把全部文件发送给客户备份工具后,调用do_pg_stop_backup进行停止备份的处理,在do_pg_stop_backup函数中,先解析原来备份的backup_label文件,获取备份起始的XLOG位置,写入XLOG_BACKUP_END到日志文件,然后调用RequestXLogSwitch进行XLOG文件段切换,方便归档快速完成。请求一次新的检查点RequestCheckpoint,写当前备份的历史文件“Backup”.文件,调用CleanupBackupHistory清除历史备份文件。如果需要等待归档则等待日志归档完成,do_pg_stop_backup停止备份结束后,调用SendXlogRecPtrResult把备份结束的XLOG位置发送给客户端备份工具,服务器端备份命令的处理流程就结束了。

START_REPLICATION对应的标识符为T_StartReplicationCmd,处理函数为StartReplication,在StartReplication函数中,首先给客户端工具发送CopyBothResponse响应消息,然后调用WalSndSetPercentCountStartLsn设置流复制开始位置,然后设置replication_started为true,启动正式的流复制过程。

2. tar压缩包格式备份

tar压缩包格式备份的处理函数为ReceiveTarFile,具体过程如下。

(1) 根据备份内容(全部还是具体表空间)和是否压缩,确定文件名称是base.tar[.gz]还是<tablespaceoid>.tar[.gz]。

(2) 打开tar文件,接收数据库服务器发送的COPY数据流,写入tar文件,直到复制完整个内容。数据库服务器往GsBaseBackup发送的数据流就是一个压缩后的tar流。

如前所述,openGauss的tar包格式是自定义的,所以需要实现解包。解包的命令为GsTar,主要有两个命令行参数。

① -D, –destination=DIRECTORY,解压后的文件存放路径;

② -F, –filename=FILENAME,需要解压的tar包。

以上内容为备份恢复机制:openGauss全量备份技术的相关内容,后续将接着分享“openGauss增量备份技术”的精彩内容,敬请期待!

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

END

智能制造一体化管理系统 [SpringBoot2 – 快速开发平台],适用于制造业、建筑业、汽车行业、互联网、教育、政府机关等机构的管理。包含文件在线操作、工作日志、多班次考勤、CRM、ERP 进销存、项目管理、EHR、拖拽式生成问卷、日程、笔记、工作计划、行政办公、薪资模块、动态表单、知识库、公告模块、企业论坛、云售后模块、生产模块、系统模块化同步模块等多种复杂业务功能。

智能制造一体化 v3.9.1 发布 ,更新内容如下:

  • 新增业务对象管理
  • 删除动态表单相关功能,融入到业务对象管理中
  • 新增工作流属性设置功能
  • 用品采购、用品领用整改为工作流低代码服务
  • 新增属性扩展字段
  • 布局新增属性控制
  • 新增操作管理
  • 重磅新闻:基础模块 (源代码) 针对星球内部用户开放,具体包含功能可查看:https://sigusoft.com/sheet/DYWZWUWZQUkFTcmh2?tab=BB08J2

erp: https://gitee.com/doc_wei01/erp-pro

OA: https://gitee.com/doc_wei01/skyeye

报表:https://gitee.com/doc_wei01/skyeye-report  有问题可以联系作者,详情请看开发计划。

效果图

效果图 效果图

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Apollo 2.1.0 已发布,包含了诸如 Spring Boot 3.0 支持、管理员工具页面增强、配置项的类型支持、支持数据库作为注册中心等重大更新。

01 Highlights

Spring Boot 3.0 支持

Apollo Java 客户端已支持 Spring Boot 3.0 版本。

管理员工具页面增强

用户管理页面增加了列表视图:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

系统配置页面增加了 PortalDB 和 ConfigDB 所有配置项的列表视图:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

开放平台权限管理页面增加了第三方应用列表视图:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

配置项的类型支持

用户现在可以修改配置项的类型,Apollo 将根据类型进行基本类型检查,现在可用的类型有 String(默认)、Number、Boolean 和 JSON。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

非 Properties 的 Namespace 比较功能

支持非 Properties 的 Namespace 比较不同集群/环境间的配置。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

支持数据库作为注册中心

Apollo 现在支持使用数据库作为服务注册中心,无需依赖第三方服务注册中心,如 Eureka、Consul、ZooKeeper 等。

不兼容更新

Flyway 数据库迁移工具从新版本开始不再支持。

02 What’s Changed

功能增强

  • 添加配置以调整属性源覆盖行为

  • 添加 Config Service Load Balancer Client 的 spi

  • 添加一个新的 API 以使用分页加载项目

  • apollo-client 支持 Spring Boot 3.0

  • apollo-client-config-data 支持 Spring Boot 3.0

  • 添加 apollo-plugin-log4j2 模块以支持 log4j2.xml 集成

  • 允许用户为 ApolloConfigChangeListener 配置以逗号分隔的命名空间

  • 为 MessageProducerManager 和 Injector SPI 添加 Ordered 接口

  • 优化 Spring-Security 防火墙拒绝请求响应 400 的问题

  • 允许用户一次关联多个公共命名空间

  • 优化开放平台授权管理 UI 体验

  • 比较配置项时添加搜索键

  • 添加一个新的 API 以使用分页加载项目

  • 阿波罗门户用户友好的用户管理页面

  • 将 Spring Session 序列化方式切换为 JSON 以兼容 Spring Security 版本更新

  • 对命名空间进行多线程排序

  • 允许用户删除 AppNamespace

  • 为 Apollo Portal 开发人员添加配置处理器

  • 添加潜在的 JSON 值检查功能

  • 支持非 Properties Namespace 比较

  • 为自定义 OIDC userDisplayName 添加一个选项

  • 为配置项添加基本类型支持

  • 一个用户友好的 Apollo 门户配置管理页面

  • 支持使用数据库作为注册中心

  • 用户可以在不重新编译项目的情况下更改 spring.profiles.active 的值

  • 为 Eureka 开启登录认证

问题修复

  • 修复 openapi item with url illegalKey 400 错误

  • 修复 ApolloBootstrapPropertySources 优先级问题

  • 修复 beanName2SpringValueDefinitions 缓存问题

  • 修复当 openapi key 的参数包含 “a[0]” 时出现 400 错误请求

  • 升级 mysql-connector-java 版本,修复可能的事务回滚失败问题

  • 修复 ‘openjdk:8-jre-alpine’ 可能导致错误的 cpu 核心数

  • 修复覆盖 JSON 类型配置为空的问题

  • 修复 deletedAt 时间戳问题

  • 修复 openapi item with url illegalKey 400 错误

  • 修复 @Transactional 无效案例

  • 修复灰度发布/回滚命名空间时出现的异常

  • 修复 LDAP 集成的 JSON 序列化问题

  • 修复 Apollo 检查 YAML 格式接口 Response Code = 500

  • 修复 create namespace with single dot 500 错误

  • 修复(安全):将 fastjson 升级到 1.2.83

  • 修复获取包含删除项命名空间信息的 openapi 接口

  • 运行测试时禁用 Spring Cloud Discovery 以加快测试过程并减少错误日志

  • 修复灰度版本的配置长度限制无法与其主版本同步的问题

  • 修复删除最后一项配置后出现空白项的问题

更多内容可以左下角阅读原文或直接访问以下链接:

  • https://github.com/apolloconfig/apollo/releases/tag/v2.1.0

  • https://github.com/apolloconfig/apollo-java/releases/tag/v2.1.0

升级后如有问题,可以反馈至 https://github.com/apolloconfig/apollo/issues。

欢迎加入我们

Apollo 社区欢迎大家以任何形式为社区做出贡献,包括但不限于文档改进、提交 issue/bug、贡献代码、Review PR、技术讨论等,一起促进开源生态的发展。

  • Apollo 官方网站:

    https://www.apolloconfig.com/

  • Apollo 仓库地址:

    https://github.com/apolloconfig/apollo

  • Apollo 公共邮箱:

    apollo-config@googlegroups.com


关于 Apollo

Apollo 项目于 2016 年在携程框架研发部诞生,初衷是为了解决公司内部配置管理尤其是中间件公共配置的管理难题,秉持着开源开放的精神,项目从第一行代码开始就在 GitHub 上开源,可以说是一个完全开放的项目。经过多年的发展,Apollo 以其功能丰富、简单易用等特性,得到了社区开发者的欢迎,也已在数百家公司中得到广泛使用。

ip2region (2.0 – xdb) 是一个离线的 IP 数据管理框架和定位库,支持亿级别的 IP 断管理,10 微秒级别的查询性能,提供了很多主流编程语言的 xdb 数据格式的生成和查询实现。

ip2region 2.10.0 更新如下:

1、增加 erlang binding 实现:https://github.com/lionsoul2014/ip2region/tree/master/binding/erlang

默认的 bench 测试结果如下:

 

2、优化 python binding maker 数据检测的实现:https://github.com/lionsoul2014/ip2region/pull/286

解析ip段出错时,抛出异常结束程序,方便查找问题。

3、修复 java binding 的 getInt2 实现的 bug:https://github.com/lionsoul2014/ip2region/issues/287

当 region 信息超过 一定长度后会触发这个 bug 导致查询读取的 region 信息不完整,最新 maven 地址:

 

ip2region 2.11.1 下载地址:

1、Gitee:https://gitee.com/lionsoul/ip2region/tree/v2.11.1

2、Github:https://github.com/lionsoul2014/ip2region/releases/tag/v2.11.1

作者: 京东零售 NutUI

NutUI

  • NutUI 4.0 Github 地址:github.com/jdf2e/nutui
  • NutUI 4.0 官网:nutui.jd.com

前言

技术日异月新、发展创新、持续的迭代已成为常态。NutUI 虽经过 v1.0、v2.0、v3.0 三次技术蜕变,仍面临很多兼容、破坏性调整的需求。随着我们自身承接业务的多样性变化及社区诉求日渐增多,大调整和升级势在必行,经过团队及社区开发者 3 个多月的开发和自测,在 2023 辞旧迎新之际我们正式发布 NutUI 4.0。

NutUI 4.0 带来了 、、、、,围绕组件丰富性、轻量化、易用性力求将组件的质量和体验提升一个台阶。

新功能

CSS Variables 动态主题

NutUI 4.0 新增 CSS Variables 动态主题,在项目运行时,通过 CSS 变量覆盖默认样式,完成定制主题、动态切换主题、暗黑模式等换肤功能,提升产品易用性。

CSS Variables 本质是一系列的样式属性,默认值被定义在  节点上,与 NutUI 3 的定制主题、在线主题定制功能相比,用户无需新建自定义 Scss 变量文件,只需通过 ConfigProvider 组件实现实时动态主题切换,使用方式更加简洁、灵活。

 

NutUI 4.0 保留原有的主题定制、在线主题定制功能,开发中根据项目的实际需求进行综合考量,按需选取适合业务场景的换肤方式。

专属图标库

NutUI 4.0 新增专属图标库。@nutui/icons-vue H5 图标包与 @nutui/icons-vue-taro Taro 图标包,专属图标库是将原 NutUI Icon 组件剥离,从而减少 NutUI 包体积 464kB,提升了轻量化体验。

专属图标库保持京东风格,使用方式包括 IconFont 全量引入,新增 SVG 按需引入方式。

按需使用

 

全量使用

 

随着专属图标库的诞生,NutUI 4.0 中所有组件内置图标的使用方式也发生了变化,都可以通过插槽进行自定义,图标样式、大小、颜色均由开发者配置,灵活度大幅提升。

 

自动按需引入

NutUI 4.0 新增更高效的自动按需引入方式。通过  实现按需引入,移除 、 插件。

与 、 相比, 支持在 Vite、Webpack、Vue CLI 等项目中自动引入组件,按需引入样式也不再强依赖于 babel,开发者可以选择 SWC、esbuild 等其他效率更高的编译工具,进而提升编译效率,Taro 小程序的开发体验也随之提升。

为了适配  插件,NutUI 4.0 对部分组件的名称与使用方式进行了调整

  • nut-fixednav -> nut-fixed-nav
  • nut-checkBoxgroup -> nut-checkBox-group
  • … …

更多组件名称调整可参考官网 从 v3 升级到 v4。

组件更完善

NutUI 4.0 除新增功能外,也加强了组件的易用性、丰富性,力求组件更高效、涵盖更多的业务场景。

新组件

NutUI 4.0 新增 2 个组件,为 NutUI 注入”新鲜血液”。

我们坚信 80 绝对不是组件库的数量极限,挖掘更多新组件,让组件库更丰富,是我们持续不断在做的事情。

  • Tour

    新增 Tour 组件,用于引导用户了解产品功能。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • PullRefresh

    新增 PullRefresh 组件,用于下拉刷新的交互操作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

易用性提升

NutUI 4.0 对 20+ 个组件做了破坏性变更,提升组件灵活度、复用率、扩展性。

NutUI 致力于打造一款好用的组件库,4.0 期间对组件进行深度优化改造,诸如功能设计不合理、灵活度不高、场景覆盖不全、扩展性不强等问题。

  • ShortPassword 不再依赖原生键盘,Demo 演示中键盘替换为 Numberkeyboard 组件,自由组合使用,灵活度更高
  • 精简 Input 组件 Props ,使其具备与 Form 组件互相搭配使用的能力,提升组件复用率
  • InfiniteLoading 组件删除下拉刷新功能,组件功能定位更加清晰,功能更加纯粹
  • Picker 组件删除内置 Popup 功能,平铺展示,满足更多的使用场景。同时也修改基于 Picker 派生出的 DatePicker 组件。
  • … …

更多组件 API 调整可参考官网 从 v3 升级到 v4

轻量化

NutUI 一直以来以为核心理念,在组件体积、NPM 依赖、构建产物等方面持续进行优化。相较于 NutUI 3.3.1,NutUI 4.0 的安装体积由 14MB 下降至 8MB,减少 42%。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

注:上述数据来自于 packagephobia

NutUI 4.0 在包体积上也有了明显的下降,由 3.81MB 下降至 2.3MB,减少 39%。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

组件瘦身

NutUI 4.0 对 10+ 个组件进行了优化,通过重构、逻辑修改、公共函数提取等方式,不仅加强了组件的健壮性,提高扩展性,也使 NutUI 的压缩前体积减少了 50kB。

  • Popover 组件进行重构,去掉第三方依赖包,实现 0 外部依赖
  • 优化 H5 与 Taro 共同需要编译函数,实现每端代码包的每行代码都是不可或缺的
  • 提取公共函数 5 个,减少冗余代码
  • … …

图标瘦身

NutUI 4.0 新增专属图标库,不仅安装包体积减少 595kB。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

同时,NutUI 4.0 删除 125 个字体图标的 font 文件,包体积减少 464kB。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

另外,专属图标库提供按需引入方式,在使用了 NutUI 的项目打包时,也只会引入组件内置图标,不会全量引入,项目包体积平均减少 50+ kB。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

副作用清除

NutUI 4.0 优化打包策略,nutui.es.js 由全量引入改为按需加载,其文件体积由 624kB 下降至 11.9kB,减少 612kB。同时,避免了副作用的产生。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

技术升级

NutUI 4.0 进行了底层架构升级来支撑不断加入的新功能,共建亦有全新体验。

  1. 构建工具升级

    NutUI 4.0 将底层构建工具从 Vite 2 升级到 Vite 4,构建时间减少了 10 秒

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  2. 库类型声明升级

    NutUI 4.0 开始,不在使用第三方插件 ,改用 vue 官方推荐的  生产类型声明文件。同时,与 Volar 插件两者结合实现检查类型错误能力。

未来

NutUI 发展至今,我们一直在学习一直在思考,除了提供更加丰富的组件、优化现有组件外,还需要做哪些事情才能服务到更多的开发者,真正做到高效、灵活、好用。

NutUI 作为移动端组件库,4.0 开始会分为  与  两个方向。针对基础组件,开发方向拆分为 H5、小程序、APP,丰富更多的 “端” 需求。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在过去,NutUI 沉淀了与高级组件库,在 NutUI 4.0 迭代同时,我们总结过往开发业务组件的经验,梳理并推出业务组件,包括商品类、优惠券类、订单类、发票类共计出 20+ 个高级组件。目前正紧张开发中,不久将与大家见面,敬请赐候~

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

最后

NutUI 的持续迭代离不开使用者和开发者的长期反馈和支持,特别感谢本次为 NutUI 4.0 做出贡献的社区开发者:@Coffee-C、@gyt95、@jxt776、@kasonyang、@mikasayw、@sjx12、@thx125、@xiaosifeng。愿大家在开源的道路上步履不停~

大家在开发中遇到任何问题,可以在 GitHub 与我们联系,或者邮件至 nutui@jd.com,也欢迎大家为 NutUI Star。

相关链接:

  • NutUI GitHub
  • NutUI 4.0 官网
  • 京东小程序官网

v3.2.0 更新内容:
1、修复文章管理未填写文章导读数据提交异常问题;
2、变更数据库名为:rxthinkcmf.evtp6.pro,跟其他版本保持统一的风格;
3、配置管理表新增配置编码字段(code)、备注字段(note);
4、更新前端系统启动脚本,本地启动命令更新为:npm run serve
5、完善系统架构细节,优化用户使用体验;
6、修复近期用户反馈的BUG;

一款 PHP 语言基于 ThinkPhp6.x、Vue、ElementUI 等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可用于快速搭建前后端分离后台管理系统,本着简化开发、提升开发效率的初衷,目前框架已集成了完整的 RBAC 权限架构和常规基础模块,前端 Vue 端支持多主题切换,可以根据自己喜欢的风格选择想一个的主题,实现了个性化呈现的需求;为了敏捷快速开发,提升研发效率,框架内置了一键 CRUD 代码生成器,自定义了模块生成模板,包括后端 PHP 文件模块和前端 Vue 端个性化模板,可以根据已建好的表结构 (字段注释需规范) 快速的一键生成整个模块的所有代码和增删改查等等功能业务,真正实现了低代码开发,极大的节省了人力成本的同时提高了开发效率,缩短了研发周期,是一款真正意义上实现组件化、低代码敏捷开发框架。

软件信息

  • 软件名称:RXThinkCMF 敏捷开发框架 ThinkPhp6.x+EleVue 版本
  • 官网网址:https://www.rxthink.cn
  • 文档网址:http://docs.thinkphp6.elevue.rxthink.cn
  • 演示地址:http://manage.thinkphp6.elevue.rxthink.cn

特别鸣谢

感谢 ThinkPHP、Vue、ElementUI 等优秀开源项目。

EventMesh 动态事件驱动的应用程序运行时,能够用动态插件式基础服务对系统进行解耦,支持不同技术栈的混合多云、复杂分布的拓扑结构等广泛用例。以事件驱动为核心,增强事件处理能力,优化编排协调过程,并提供联邦治理机制。为企业实现数字化转型提供了应用进程间通信的全套解决方案,帮助企业降低系统复杂度,节约开发维护成本。

 EventMesh v1.8.0 是进入 Apache 孵化后更新的第 7 个版本,继 v1.7.0 版本提供了 workflow 能力后,本次版本最主要的功能特性是,EventMesh Dashboard 提供了与 workflow 的集成与交互,可以通过 EventMesh Dashboard 对 workflow 进行编排与配置,初步实现了界面化的交互设计,如下图所示:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

同时,为大家带来了 12 个新增特性,完善修复了 3 个可能的安全问题,具体有哪些,请大家下滑获取。关于使用分布式应用框架进行提效的深度解读、如何实现数据联合治理?等话题的解决方案,欢迎加入社区详细了解!

GitHub repo:https://github.com/apache/incubator-eventmesh

Gitee repo:https://gitee.com/WeBank/EventMesh

Website:https://eventmesh.incubator.apache.org/

小助手 ID:EventMesh

EventMesh v1.8.0 特性

  • 特性 #2888 Complete EventCatalog features
  • 特性 #2894 Complete Dashboard Workflow Features
  • 特性 #2865 Dashboard-add workflow swagger docs
  • 特性 #2866 Dashboard-add event catalog swagger docs
  • 特性 #2790 Jaeger tracing plugin docs
  • 特性 #2867 Dashboard-add workflow controller cmd module
  • 特性 #2868 Dashboard-add event catalog controller cmd module
  • 特性 #2808 Dashboard-Add event catalogs
  • 特性 #2807 Dashboard – Add Workflows
  • 特性 #2806 Dashboard – New style for the navigation menu
  • 特性 #2789 Jaeger tracing plugin service
  • 特性 #2788 Jaeger tracing plugin config

EventMesh v1.8.0 增强

  1. 增强 #2576 Enhancement of the config management for the project
  2. 增强 #2894 Optimize workflow save interface
  3. 增强 #2880 Optimize workflow dashboard controller module
  4. 增强 #2181 Workflow Feature Implementation: Catalog Management
  5. 增强 #2180 Workflow Feature Implementation: Workflow Management
  6. 增强 #2863 eventmesh-server-go module add golangci-lint command in Makefile
  7. 增强 #2852 optimize code to reduce almost the same code for updating clients and subscriptions in different processor
  8. 增强 #2702 Some optimizations for collections
  9. 增强 #2693 SendAsyncEventProcessor judgment blanks can be simplified
  10. 增强 #2691 Interface methods are public by default so you can remove the public
  11. 增强 #2642 go sdk common util module add test case
  12. 增强 #2640 Refine rabbitmq connector unit test
  13. 增强 #2638 refactor go sdk id module test
  14. 增强 #2196 Workflow Feature Implementation: Workflow execution metrics
  15. 增强 #2190 Workflow Feature Implementation: Event Filter/Validate
  16. 增强 #2192 Workflow Feature Implementation: Integrate EM, implement queue based on MQ

EventMesh v1.8.0 修复

  • 漏洞 #2855 eventmesh-sdk-go test error
  • 漏洞 #2849 TCP Server will throw stack overflow error when subscribing because of calling self method recursively
  • 漏洞 #2845 Fix IOException in SSLContextFactory

Scala.js 团队发博客庆祝该项目走过第一个十年。

Scala.js 是一个将 Scala 语言编译成 JavaScript 的工具,可以直接在浏览器上使用 Scala 编写程序。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

最初的Scala.js 是 EPFL LAMP 的一个单人项目,于 2013 年 2 月 5 日迎来了首次提交,并在 2013 年 6 月的 Scala Days 上首次展示,当时受到了热烈欢迎 —— 虽然它输出了 16 MB 大小的“Hello world”。随后一小群早期的爱好者聚集在一个邮件列表中,为该项目提供有价值的早期反馈,随着讨论的增加,一个人的项目很快成长为一个两人核心团队以及几十个爱好者。

起初 Scala 生态系统的大多数库都不支持 Scala.js,只有一些核心用户使用 Scala.js 构建了新的库和测试框架。但随着 Scala.js 0.6.0 脱离了实验性环境,转为生产可用,Scala.js 的采用显著增长, Scala 生态系统中越来越多的库开始支持 Scala.js。如今,大多数不专门针对 JVM-only 特性的库都为 Scala/JVM 和 Scala.js 交叉发布。在 2021 年 8 月发布的 Scala.js 1.7.0 以来,Scala.js 的每个版本的已知错误都是 0 ,覆盖了整个核心存储库:编译器后端和 Scala 链接器。

回想发布之初,将 Scala 编译成 JavaScript 还像一个梦想,但如今它已成为一种日常。如今 Scala.js 已经是一项非常成熟的技术,具有稳定核心、充满活力的库生态以及热情的用户和贡献者社区。在 Jetbrains 2022 开发者调查和 Scala 2022 现状调查中, Scala 开发者分别有 12% 和 17% 的 Scala.js 用户。 在 Maven Central 统计报告中,Scala.js 核心工件每月的下载量超过 100,000 次。

为推动社区繁荣发展,打造开源操作系统创新生态, openKylin社区根据领域划分了不同的SIG组,并积极开展各种技术研究和创新。截至目前,社区新增共有57个SIG组在运行,接下来,让我们一起盘点2023年1月份openKylin社区SIG组的最新技术进展:

 

openKylin社区技术进展与成果

一、UKUI SIG

UKUI(Ultimate Kylin User Interface) SIG小组致力于桌面环境相关软件包的规划、维护和升级工作,满足各种设备和用户需求的桌面环境程序,主要包含程序启动器(开始菜单)、用户配置、文件管理、登录锁屏、桌面、网络工具、快捷配置等,为用户提供基本的图形化操作平台。桌面核心组件开发工具以Qt、C++为主,宗旨是始终如一地提升系统的操作体验,提供集稳定性、美观性、流畅性和便捷性为一体的桌面环境。1月进展如下:

  • 分级冻结:进行第二轮提测,同步demo和用例;
  • 企业WIFI新增LEAP、FAST和PWD三种认证方式;
  • 解决控制面板、网络、触摸、会话管理器、日历、文管、睡眠唤醒、多语言等问题;
  • 修复版权信息、电源适配器、无法删除用户、快捷键、电源管理、通知中心、全局搜索、控制面板、托盘电源、任务栏、侧边栏等问题。

欢迎各位感兴趣的社区开发者加入我们,一起打造openKylin桌面系统稳定易用的桌面环境!

二、RISC-V SIG

本SIG组主要负责RISC-V架构开源软件包的维护,发布openKylin的RISC-V版本,进行软件包构建、系统构建等工作。1月份RISC-V SIG组进展如下:

  • 制作并提测openKylin0.9.5-beta版本的hifive、visionfive、曳影1520三个镜像;
  • 修复了桌面显示、系统安装卸载、tty显示、打印机报错等问题;
  • 开发板适配解决cpu占用100%问题;
  • 适配visionfive2开发板。

欢迎所有对RISC-V开发平台技术方向感兴趣的爱好者加入到RISC-V SIG!

三、Release SIG

Release SIG主要负责协调各个SIG组,把控版本开发进度和风险,制定版本发布计划,完成版本发布工作等。Release SIG组1月主要进展如下:

  • 0.9.5 RC版本提测(x86,riscvRISC-V);
  • 完成0.9.5版本发布相关工作:里程碑bug以及RISC-V和arm版本等问题修复;
  • 0.9.5版本阶段总结复盘,后续工作计划讨论;
  • 完成5个高危安全漏洞修复更新推送。

欢迎所有对openKylin社区版本集成、版本管理、版本发行等工作感兴趣的爱好者加入到Release SIG!

四、Packaging SIG

Packaging SIG负责维护openKylin社区的软件包打包规范,维护公共软件包,以及协调和决策社区版本发布过程中的包依赖问题。1月主要进展如下:

  • paddle、libzstd-1.5.2、Perl 5.36.0编译处理,编写perl特性说明文档;
  • 解决docker运行失败、cryptsetup编译问题;
  • 从上游社区自主构建containerd, runc, libseccomp,libqapt,abseil,openldap;
  • 修复ukui-power-manage、gcc-defaults、libsoup2.4、accountsservice 0.6.55问题;
  • 上传kylin-sso-client,kylin-software-center,kylin-kmre-window,paddlepaddle、libzstd、isl、gmp、autoconf2.6等;
  • 新增自主构建软件包13个。

欢迎所有对openKylin社区软件自主选型、编译打包工作感兴趣的社区爱好者加入我们!

五、Framework SIG

Framework SIG致力于为openKylin社区提供集程序编辑、编译、调试、发布、分析等全套开发功能的编程环境,涵盖通用集成开发环境、编译工具链、运行时环境、类库等。SIG初期重点研制高效率、跨平台、插件化、易调试的通用集成开发环境,支持C、C++、Java、Go、Fortran、Python、JavaScript等多种标准编程语言,涵盖编码、编译、调试、性能分析、软件交付等一整套开发流程,满足openKylin平台上软件开发需求。1月主要进展如下:

  • 项目创建插件优化c语言项目创建模板,调整创建过程的逻辑和相应的修改数据功能。

欢迎所有对openKylin社区应用集成开发环境感兴趣的爱好者加入到Framework SIG!

六、GPU SIG

openKylin GPU SIG组致力于GPU驱动相关技术研究,包括OpenGL、OpenCL、Vulkan、VDPAU和VAAPI等。提供GPU相关软件包的技术规划、设计、开发、维护和升级服务,共同推动国产GPU技术发展。GPU SIG组1月份进展如下:

  • 和格兰菲、象帝先等GPU企业交流合作,并完成加入GPU SIG组流程。

欢迎所有对CPU驱动、国产GPU技术、显示等相关领域感兴趣的社区小伙伴加入GPU SIG组!

七、InternationalPromotion SIG

本SIG组负责openKylin操作系统的国际化推广,开展国际交流会议,提升国产操作系统国际影响力,致力于世界各地爱好者加入openKylin社区建设。1月份进展如下:

  • 举办社区首届国际交流活动,与南开大学留学生交流讨论社区国际推广相关合作。

欢迎国内外对openKylin操作系统国际推广工作感兴趣的小伙伴加入到InternationalPromotion SIG,共同推动openKylin迈向国际!

八、Infrastructure SIG

Infrastructure SIG负责openKylin社区的基础平台系统功能的开发、维护。1月主要进展如下:

  • CI平台增加PR提示,解决了检查结果404报错、版本号对比错误等问题;
  • 数字看板增加外部开发者总积分排名接口。

欢迎所有对openKylin社区基础设施平台开发维护感兴趣的爱好者加入到Infrastructure SIG!

九、QA SIG

QA SIG组致力于提升openKylin社区版本质量,包括社区版本测试、质量保障等。1月主要进展如下:

  • RC版本回归测试;
  • bug复现协助确认;
  • 处理码云issue2个,计算贡献值;
  • RC版本0105-0109版本测试、release版本测试、RISC-V架构测试、更新升级测试;
  • 输出0.9.5版本公测方案。

欢迎所有对openKylin社区版本测试、质量管理感兴趣的社区爱好者加入我们!

十、Security Governance SIG

openKylin SecurityGovernance SIG通过接收和响应openKylin社区的产品安全问题报告、提供社区安全指导,开展安全治理等活动提升社区产品的安全性。1月主要进展如下:

  • 调研CodeCheck代码扫描工具;
  • “诊脉”漏扫框架(genmai),调试dbus漏洞扫描模块,加载POC验证;
  • 完成漏洞检测工具baseline框架开发,以及添加了9个poc;
  • 安全编码规范:调研了CodeCheck代码扫描工具的规则配置,规则文件导入导出功能。

欢迎所有对openKylin版本安全全漏洞挖掘/验证、安全漏洞修复等安全方面工作感兴趣的社区爱好者加入我们!

关于openKylin社区SIG

openKylin(开放麒麟)社区是一个自由开放的社区,社区中所有的SIG小组都是开放的,任何人和组织都可以参与。你可以选择加入已有SIG,也可以选择创建新的SIG。截至目前,openKylin社区已有57个SIG在运行,包括Architecture、Infrastructure、Release、Kernel、Security、Compatibility等。

如果您对此感兴趣,想要加入openKylin(开放麒麟)社区,参与SIG贡献,可 “https://www.openkylin.top/sig/index-cn.html  ” 了解更多详细内容。

 

关于openKylin社区

openKylin(开放麒麟)社区旨在以“共创”为核心,在开源、自愿、平等、协作的基础上,通过开源、开放的方式与企业构建合作伙伴生态体系,共同打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态繁荣发展。

社区首批理事成员单位包括麒麟软件、普华基础软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、心科技、中国电科32所、技德系统、北京麟卓、先进操作系统创新中心等13家产业同仁和行业机构。

 

 

来源:openKylin

审核:openKylin

2023年1月26日,Apache 软件基金会 (ASF) 官方宣布 Apache bRPC 正式毕业,成为 Apache 顶级项目 (TLP)。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Apache bRPC 是由百度初始创立并持续贡献的工业级别 RPC 开源项目,在 2018 年正式贡献给 Apache 软件基金会进行项目孵化,2022年12月24日经过 Apache 董事会集体投票表决,Apache bRPC 项目顺利毕业,成为 Apache 软件基金会顶级项目(TLP),这是百度继 ECharts 和 Doris 之后,又一里程碑式的开源项目。

Apache ECharts 顺利毕业,成为 ASF 顶级项目
Apache Doris 从 Apache 基金会毕业,正式成为 Apache 顶级项目!

关于 Apache bRPC

bRPC于2014年诞生于百度基础架构部,用C++编写的工业级RPC框架,常用于搜索、存储、机器学习、广告、推荐等高性能系统。2017年正式在 GitHub 进行开源,并于2018年11月正式捐献给全球顶级开源社区 Apache 软件基金会(ASF),对外开源版本的名称为 Apache bRPC,成为 ASF 孵化级项目。

据介绍,bRPC以功能全、可扩展、高性能等特性得到越来越多用户的认可和使用,经过四年多的孵化,bRPC开发者数量增长数倍、在GitHub上的Star数也超过14.4K,目前已覆盖了互联网、人工智能、搜索、推荐、电商和教育等多个行业和领域,被百度、爱奇艺、作业帮、字节跳动、京东、拼多多、滴滴、B站、vivo、小红书、第四范式、欢聚时代、shopee等公司广泛使用并对该项目进行持续贡献,线上服务实例数已超过600W,现已成为业界广受欢迎的开源RPC框架之一。

Apache bRPC 成长史

  • 2014年,baidu-rpc在百度基础架构部诞生

  • 2016年,baidu-rpc在百度得到大规模落地和实践

  • 2017年,bRPC在GitHub上正式开源

  • 2018年,百度将 bRPC 捐献给 Apache 软件基金会并命名为 Apache bRPC,进入孵化器

  • 2021年,bRPC社区发布第一个正式版本 1.0.0

  • 2022年,正式完成商标捐赠,推动 Apache bRPC 完成毕业,成为 Apache 软件基金会顶级项目(TLP)

截至2023年1月,Apache bRPC 已在GitHub上获得14.4K Stars ,拥有超过130名贡献者,成为国内最活跃的开源社区之一。

Apache bRPC 社区官方链接

  • Apache bRPC官方网站:https://brpc.apache.org/
  • Apache bRPC GitHub:https://github.com/apache/brpc
  • Apache bRPC 开发者邮件组:dev@brpc.apache.org
  • 订阅 Apache bRPC 邮件列表
    发送任意主题和内容到 dev-subscribe@brpc.apache.org
    根据回复完成订阅

作者:vivo 互联网前端团队- Yang Kun

本文是上篇文章《Node.js 应用全链路追踪技术——全链路信息获取》的后续。阅读完,再来看本文,效果会更佳哦。

本文主要介绍在Node.js应用中, 如何用全链路信息存储技术把全链路追踪数据存储起来,并进行相应的展示,最终实现基于业界通用 OpenTracing 标准的 Zipkin 的 Node.js 方案。

一、背景

目前业界主流的做法是使用分布式链路跟踪系统,其理论基础是来自 Google 的一篇论文 《大规模分布式系统的跟踪系统》。

论文如下图所示:

图片

(图片来源:网络)

在此理论基础上,诞生了很多优秀的实现,如 zipkin、jaeger 。同时为了保证 API 兼容,他们都遵循 OpenTracing 标准。那 OpenTracing 标准是什么呢?

OpenTracing 翻译为开发分布式追踪,是一个轻量级的标准化层,它位于应用程序/类库和链路跟踪系统之间的一层。 这一层可以用下图表示:

图片

从上图可以知道, OpenTracing 具有以下优势:

  • 统一了 API ,使开发人员能够方便的添加追踪系统的实现。

  • OpenTracing 已进入 CNCF ,正在为全球的分布式链路跟踪系统,提供统一的模型和数据标准。

大白话解释下:它就像手机的接口标准,当今手机基本都是 typeC 接口,这样方便各种手机能力的共用。因此,做全链路信息存储,需要按照业界公认的 OpenTracing 标准去实现。

本篇文章将通过已有的优秀实现 —— zipkin ,来给大家阐述 Node.js 应用如何对接分布式链路跟踪系统。

二、zipkin

2.1 zipkin 是什么?

zipkin 是 Twitter 基于 Google 的分布式追踪系统论文的开发实现,其遵循 OpenTracing 标准。

zipkin 用于跟踪分布式服务之间的应用数据链路。

2.2 zipkin 架构

官方文档上的架构如下图所示:

图片

为了更好的理解,我这边对架构图进行了简化,简化架构图如下所示:

图片

从上图可以看到,分为三个部分

第一部分:全链路信息获取,我们不使用 zipkin 自带的全链路信息获取,我们使用 zone-context 去获取全链路信息

第二部分:传输层, 使用 zipkin 提供的传输 api ,将全链路信息传递给 zipkin

第三部分: zipkin 核心功能,各个模块介绍如下:

  • collector 就是信息收集器,作为一个守护进程,它会时刻等待客户端传递过来的追踪数据,对这些数据进行验证、存储以及创建查询需要的索引。

  • storage 是存储组件。zipkin 默认直接将数据存在内存中,此外支持使用 ElasticSearch 和 MySQL 。

  • search 是一个查询进程,它提供了简单的 JSON API 来供外部调用查询。

  • web UI 是 zipkin 的服务端展示平台,主要调用 search 提供的接口,用图表将链路信息清晰地展示给开发人员。

至此, zipkin 的整体架构就介绍完了,下面我们来进行 zipkin 的环境搭建。

2.3 zipkin 环境搭建

采用 docker 搭建, 这里我们使用 docker 中的 docker-compose 来快速搭建 zipkin 环境。

docker-compose.yml 文件内容如下:


在上面文件所在的目录下执行 docker-compose up -d 即可完成本地搭建。

搭建完成后,在浏览器中打开地址 http://localhost:9411 ,会看到如下图所示页面:

图片

接着打开地址 http://localhost:9200 ,会看到如下图所示页面:

图片

至此, zipkin 的本地环境就搭建好啦。 下面我就将介绍 Node.js 应用如何对接 zipkin。

三、Node.js 接入 zipkin

3.1 搞定全链路信息获取

这个我在 《Node.js 应用全链路追踪技术——全链路信息获取》 文章中,已经详细阐述了,如何去获取全链路信息。

3.2 搞定传输层

因为 zipkin 是基于 OpenTracing 标准实现的。因此我们只要搞定了 zipkin 的传输层,也就搞定了其他主流分布式追踪系统。

这里我们用到了 zipkin 官方提供的两个 npm 包,分别是:

  • zipkin

  • zipkin-transport-http

zipkin 包是官方对支持 Node.js 的核心包。 zipkin-transport-http 包的作用是将数据通过 HTTP 异步发送到 zipkin 。

下面我们将详细介绍在传输层,如何将将数据发送到 zipkin 。

3.3 传输层基础封装

核心代码实现和相关注释如下:


至此,传输层的基础封装就完成了,我们抽离了 baseRecorder 出来,下面将会把全链路信息接入到传输层中。

3.4 接入全链路信息

这里说下官方提供的接入 SDK ,代码如下:


上面的方式缺点比较明显,需要额外去传递一些东西,这里我们使用上篇文章提到的 Zone-Context , 代码如下:


对比两者,明显发现, Zone-Context 的实现方式更加的隐式,对代码入侵更小。这也是单独花一篇文章介绍 Zone-Context 技术原理的价值体现。

自此,我们完成了传输层的适配, Node.js 应用接入 zipkin 的核心步骤基本完成。

3.5 搞定 zipkin 收集、存储、展示

这部分中的收集、展示功能, zipkin 官方自带完整实现,无需进行二次开发。存储这块,提供了 MySQL 、 Elasticsearch 等接入方式。可以根据实际情况去做相应的接入。本文采用 docker-compose 集成了 ElasticSearch 。

四、总结

自此,我们已经完成基于业界通用 OpenTracing 标准实现的 zipkin 的 Node.js 方案。希望大家看完这两篇文章,对 Node.js 全链路追踪,有一个整体而清晰的认识。

参考资料:

  1. zipkin 官网

四是无 Sidecar 模式的服务网格可供选择。Istio 推出了 Ambient 部署模式,这是一种新的 Istio 数据平面模式,旨在简化操作、扩大应用兼容性并降低基础设施成本。用户可以选择将 Ambient Mesh 集成到其基础设施的网格数据平面,放弃 sidecar 代理,同时保持 Istio 的零信任安全、遥测和流量管理等核心功能。

五是 WebAssembly 崛起。WebAssembly 正在发展成为云原生环境中跨平台、多语言的沙箱环境,甚至可以替代容器运行时,在 Kubernetes 中编排调度。 WasmEdge、KubeEdge、Istio 等项目可以从控制平面无缝编排 Wasm 工作负载。

DPDK 全称为 Data Plane Development Kit ,是近年来在高速网络通信行业中炙手可热的一种网络报文处理加速框架。DPDK 从十年前诞生直至发展到今天已经可以支持业界主流的高端网卡以及各类加速硬件设备,同时也支持主流的各个CPU 体系结构(可以运行于 X86, Arm, Power 等平台)。同时也可以运行于 Linux/FreeBsd/Windows 等主流操作系统之上。DPDK因为其优异的性能指标被广泛的应用于网关/负载均衡/SDN/虚拟交换的各个场景。

本文主要介绍 DPDK 中的 libgraph 设计思想以及实现,libgraph 的设计思想源自于开源项目 Vector Packet Processor(VPP)。VPP 中的向量包处理优化方案是 libgraph 的参照对象。因为 VPP 项目整体是一个非常全面的解决方案,从中剥离核心的设计框架为其它轻量级项目所用就变得很有意义。这也是 Libgraph 的产生背景。虽然它目前还是DPDK 中相对比较新的 lib,但是其优秀的设计思想还是值得学习参考。

下面将首先介绍 libgraph 架构的核心概念:标量和向量包处理(scalar vs vector packet processing)以及它们之间的区别。然后再介绍 libgraph 中的核心组件,以及它们之间的联系和交互方式。最后,我们将介绍 libgraph 的具体用例以及优缺点。

背景

DPDK libgraph 是一个向量包处理的框架。与传统的标量包处理模型(一系列函数负责处理一个数据包,重复直到所有数据包处理完毕)相比,向量数据包处理模型的差别则在于一系列的函数处理一批数据包。这种方法的主要目的是解决当 pipeline 变复杂时所遇到 i-cache miss 较高的问题。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

<p align=center>标量处理模型 vs 向量处理模型</p>


标量处理模型在性能上不如向量处理模型的另一个原因,就是在不同处理函数(业务逻辑)之间,报文传递到下一个处理函数的方式上有所不同。前者只是简单地用 pointer assignment 的方法来传递,若处理基于不同批次的情况下,由于低效的 pointer assignment,会导致处理一批报文时性能低下。

而对于向量包处理模型而言,向量包处理模型反而可以减少上述标量处理模型因批处理而导致性能不理想的情况。这是因为在向量模型中,报文在业务逻辑之间的传输除了可以通过最原始的 pointer assignment 之外,也可以通过优化的 memory copy,最优情况下可以仅仅交换pointer。它不仅消除了标量处理模型会遇到的问题,而且在设计 pipeline 时还可以实现更优的内存分配并与业务逻辑解耦。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图片來源:https://fd.io/gettingstarted/technology/

<p align=center>向量处理模型,graph 有 1 个起点(dpdk-input, n packets)以及 7 个业务逻辑</p>


Graph 框架优点

总体而言,与传统的标量处理模型相比,以下概括了 graph 框架主要的优势

  1. 更好的 i-cache 管理,更好的icache locality。
  2. 灵活的 pipeline 模型(pipeline 框架是从业务逻辑中抽象出来的)
  3. 减少 pointer 复制
  4. Node 可以累积多个先前 node 所传递的报文,因此批处理性能更好
  5. 表驱动节点调度(便于支持QoS)而不是 hardcode pipeline

Graph 工作流程

现在来说一下整体上 graph 框架的工作流程。如上图所述的一样,一个 graph 是由不同的节点 (node) 所组成的。与传统的标量模型相比,两个框架其实都包含一样的逻辑。最大的不同是 graph 框架中 node 节点在运行时与其他 node节点的交互方式,或者具体地来说,是报文在node节点中的传递方式。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

一个 node 中的 报文 传送到不同的 node,home run 情况 (优化案例) 以及正常 enqueue情况;动态增加 node 的 objects 队列 大小


Node 的 Object 队列大小

默认情况下,每个 node 都有一个 RTE_GRAPH_BURST_SIZE 大小(node->size)的 object 队列,它定义了该 node 中可以容纳和处理的报文数量。如果一个 node 试图将报文排队到下一个 node,但下一个 node 已经有报文在排队并且已满(例如在 l3fwd 中,用户可以有多个接收队列/ node 排队到同一个下一个 node pkt_cls),node 的 object 队列大小将会被动态的加倍。这意味着 node 具有批处理的优势,因为它可以累积报文。

注意:当前 API 不支持 node 的 object 队列大小在增大后再缩小

Objs 的传递 — ‘home run’/normal enqueue

报文转换有两种类型,一种是正常的 enqueue,另一种是优化情况,“home run”。

Normal enqueue

在上面介绍 node 的 object 队列大小部分,我们提到将报文排队到下一个 node 的概念。对于普通的 enqueue,就是简单的将当前 node 中处理好的报文,通过使用 rte_memcpy / pointer assignment 作为传递方法, enqueue 到下一个可能的 node。

Home run

Home run 则是一种优化的情况,它不像普通的 enqueue 把报文复制到下一个 node,而是简单地交换当前 node 和下一个 node 之间的有关于报文的指针(例如报文、报文数目),从而消除 memory copy / pointer assignment 的开销。当满足以下条件时,home run 才会被触发:

  • 所有已处理好的报文都将前往同一个 node
  • 下一个 node 的 object 队列没有任何需要处理的报文 (node 的 object 队列为空)

Graph 遍历 node的流程


注意:rte_graph_walk 调用 struct rte_graph 的内存布局以及 circular buffer (cir_start) 可以参考后面组件的介绍

graph walk 的概念简单明了,它总是有次序地去完成一系列操作:

  1. 21行:定位下一个需要处理的 node
  2. 23行:准备下一个需要处理的 node 的 objects /报文
  3. 29行:处理定位好的 node
  4. 32行:检查 graph walk 是否完成

在 graph walk 层面来看,最重要的就是第一步:定位下一个要处理的 node。DPDK 的 graph 框架利用了 circular buffer 和附带的 head 和 tail 指针定位下一个 node,如果 head 不等于 tail 指针,这就代表了 circular buffer 里有需要处理的 node,而在 libgraph 库中,这些待处理的 node 也被称为 pending stream。

回到第一步,它是以一个 circular buffer (cir_start[head++]) 的 head 来定位,或者更详细地从 graph walk 的始点说起,由于 graph->head 在初始化的时候被指定为 -src_node_count (负的 source node 数量,可以参考下一部分 rte_graph 的内存布局),所以 cir_start[head] 其实就是第一个 source node。那么 tail 的作用是什么?libgraph 是如何利用它来动态修改 circular buffer 和 pending stream 帮助 node 的定位呢?

在回答这些问题之前,我们首先来了解下面两个 API 函数,分别是 和 。


每次当前 node 需要将报文 enqueue 到任何下一个 node 时,都需要调用 去检查以下内容:

  • 下一个 node 是否已被添加到 pending stream (待处理的 node)
  • 是否需要为下一个 node 分配内存

其中变量 idx 和 space 分别表示下一个 node 已有的报文数目,以及当前 node 想要enqueue的数目。


而API 函数 目的就是调整 tail 把下一个 node 放到 pending stream 里。

下图展示了报文的传递跟 node 是如何被加到 pending stream 的关系。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

注意一下 node 添加到 pending stream 的顺序取决于处理报文时的顺序。例如,如果报文 1 和 3 到 node2,而 报文 2 和 4 到 node3,那么 circular buffer/pending stream 中 node1 和 node2 的顺序将被交换。

组件

libgraph 的核心组件是 graph 和 node。graph 作为调度 node 的全局数据结构,而 node 则是用来封装业务逻辑。

Graph

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

<p align=center>3 个node; 1 个 source node (源节点)和 2 个 node (非源节点)的 graph 结构</p>


上图显示了具有 3 个节点的 graph 结构,包含以下关键组件:

graph_list

存储所有创建成功的 graph。如果 graph 创建成功,graph 会被添加到 graph_list 中。与传统的 main loop 设计相比(把函数直接挂载到 CPU 核上),用户可以透过这种管理模式把 graph_list 中的 graph 映射到不同的 CPU 核上。

graph->node_list

每个创建成功的 graph 中的 node_list 都包含了先前添加到 graph 中的 node。注意此处使用的是 graph_node 结构,其中包含了本身的 node(struct node* node)以及其相邻的 node。

struct graph_node vs struct node

struct node 结构体的用法仅仅是用来描述对应的 node,和 graph 是没有关系的。而 struct graph_node 其实就是把 struct node 包装了一层,主要目的就是强调这个 node 在一个 graph 中。

struct rte_graph

接下来介绍 struct rte_graph(rte_*: runtime 时所用到的数据结构)的内存布局,建议先把先前的 graph walk 部分浏览一遍,以更好了解 rte_graph 是如何被使用。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

<p align=center>rte_graph 内存布局。 注意此例除有 3 个 source node,而待处理的流 (pending stream)中有 2 个节点。</p>


现在可以更清楚地看到 struct graph 及其子组件 struct node 的目的是保存内部数据/用于设计,而 struct rte_graph 和 struct rte_node 是用于 runtime。runtime 的内存布局包含了所有必需的组件,比如所有source node、non-source nodes 以及 pending steam 的 node(从cir_start 开始)。

先前我们提到在 graph walk 时需要从 source node 开始,以及需要利用 circular buffer 来定位待处理的node。现在透过分析内存布局的帮助下,我们能更好地去想象 graph walk 是如何从 cir_start[-src_node_count] 开始,直到再没有任何 pending stream (head 等于 tail)为止。

struct node

理解了 graph 的运作原理后,我们现在讨论一下底层的关键组件 node。先前我们已经提到 graph_node 和 node 的部分区别,其实关键区别在于 node 实际包含了什么信息。


<p align=center>Struct node 结构体 (lib/graph/graph_private.c)</p>


向量包处理的概念是一次处理一个向量/一批报文,所以一个节点其实就是代表一个function,只不过处理对象是一批报文。​

一个节点除了包含相邻 node 的信息外,还包含有助于识别 node 的基本信息,例如 id、parent_id、flags、name 等。最重要的是,除了核心处理函数 rte_node_process_t process 以外,它还包含了在创建、销毁 graph 时运行的 init 和 fini 函数。 init 函数的一些实际可以是配置路由表、定义 ACL 规则等。

Node 的注册

node 的注册是通过 contructor scheme 的 (attribute((constructor)))来完成的。下面显示了一个非常简单的 node 注册示例。需要强调的是: .process 的函数定义突出了向量数据包处理的概念 (需要处理的报文 (objs) 及其数量 (nb_objs))。


构造一个 print Hello World 的 source node


source node vs non-source node

在任何处理模型都必须有一个起点,而在 libgraph 中每个 graph pipeline 都必须从 source node 开始。而对于非 source node 来说,它们则是依赖于先前 node 是否会将报文排队到它们的节点,因此它们只会出现在动态的 pending stream 中。

总结

本文介绍了 DPDK graph API 的框架以及它内部是如何实现的。 graph 框架的优势在于减少 i-cache miss 、更好的抽象业务逻辑,以及提高用户设计 pipeline 的灵活度,但 graph 框架也同时带来下列缺点:

  • 引入潜在内存安全风险
  • 复杂的代码逻辑,需要大量的测试工作
  • 初学者学习曲线陡峭

总体而言,与传统的 pipeline 模式相比,graph 框架也会出现 tradeoff。使用者需要考虑其业务逻辑的复杂程度,才能有计划地设计出可管理的 graph pipeline。graph 模型更适用于 pipeline 比较复杂的场景。有兴趣的读者可以持续关注后期即将发布的《DPDK Graph Pipeline 框架示例和性能分析》,以更好地理解 DPDK libgraph 的性能和实际用途。

今天故事的主角还是大家熟识的二狗子。二狗子拿到了一笔项目奖金,在好好犒劳了自己一顿后,决定把剩下的钱在银行存个定期。

他用浏览器访问了 www.bank.com,输入了用户名和密码后,成功登录。

bank.com 返回了 cookie 用来标识二狗子这个用户。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

不得不说,浏览器是个认真负责的工具,它会把这个 cookie 记录下来,以后二狗子每次向 bank.com 发起 HTTP 请求,浏览器都会准确无误地把 cookie 加入到 HTTP 请求头部中,一起发送到 bank.com,这样 bank.com 就知道二狗子已经登陆过了,就可以按照二狗子的请求来做事情,比如查看余额、转账取钱。

二狗子存完钱,看着账户余额,心中暗喜。于是,他打开了 www.meinv.com,去看自己喜欢的电影。

但二狗子不知道的是,浏览器把 meinv.com 的 HTML、JavaScript 都下载到本地,开始执行。而其中某个 JavaScript 中,偷偷创建了一个 XMLHttpRequest 对象,然后向 bank.com 发起了 HTTP 请求 。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

浏览器严格按照规定,把之前存储的 cookie 也添加到 HTTP 请求中。但是 bank.com 根本不知道这个 HTTP 请求是 meinv.com 的 JavaScript 发出的,还以为是二狗子发出的。bank.com 检查了cookie,发现这是一个登录过的用户,于是兢兢业业地去执行请求命令,二狗子的个人信息就泄露了。(ps. 实际中实施这样一次攻击不会这么简单,银行网站肯定是做了其他很多安全校验的措施,本故事只是用来说明基本原理。)

可怜的二狗子还不知道发生了什么,已经遭受了钱财损失。那我们来帮他复盘一下为什么会发生这种情况。

首先,每当访问 bank.com 的时候,不管是人按钮访问链接,还是通过程序的方式,存储在浏览器的 bank.com 的 cookie 都会进行传递。

其次,从 meinv.com 下载的 JavaScript 利用 XMLHttp 访问了 bank.com。

第一点我们是无法阻止的,如果阻止了,cookie 就丧失了它的主要作用。

对于第二点,浏览器必须做出限制,不能让来自 meinv.com 的 JavaScript 去访问 bank.com。这个限制就是同源策略。

同源策略

浏览器提供了 fetch API 或 XMLHttpRequest 等方式,它们可以使我们方便快捷地向后端发起请求,取得资源,展示在前端上。而通过 fetch API 或 XMLHttpRequest 等方式发起的 HTTP 请求,就必须要遵守同源策略 。 那什么是同源策略呢?同源策略(same-origin policy)规定了当浏览器使用 JavaScript 发起 HTTP 请求时,如果是请求域名同源的情況下,请求不会受到限制。但如果是非同源的请求,则会强制遵守 CORS (Cross-Origin Resource Sharing,跨源资源共享) 的规范,否则浏览器就会将请求拦截。

那什么情况下是同源呢?同源策略非常严格,要求两个 URL 必须满足下面三个条件才算同源:

1、协议(http/https)相同;

2、域名(domain)相同;

3、端口(port)相同。

举个例子:下列哪些 URL 地址与 https://www.bank.com/withdraw.html 属于同源?

  • https://www.bank.com/save.html (✅)

  • http://www.bank.com/withdraw.html (❌,协议不同)

  • https://bank.com/login.html (❌,域名不同)

  • https://www.bank.com:8080/withdraw.html (❌,端口不同)

因此,当我们请求不同源的 URL 地址时,就会产生一个跨域 HTTP 请求(cross-origin http request)。

例如想要在 https://www.upyun.com 的页面上显示来自 https://opentalk.upyun.com 的资讯内容,我们使用浏览器提供的 fetch API 来发起一个请求:


这就产生了一个跨域请求,跨域请求则必须遵守 CORS 的规范。

当请求的服务器没有配置允许 CORS 访问或者不允许来源地址的话,请求就会失败,在 Chrome 的开发者工具台上就会看到以下的经典错误:


那在实际应用中,我们该如何正确地设定 CORS 呢?

什么是 CORS

CORS 是针对不同源(域)的请求而制定的规范。浏览器在请求不同域的资源时,被跨域请求的服务端必须明确地告知浏览器其允许何种请求。只有在服务器允许范围内的请求才能够被浏览器放行并请求,否则会被浏览器拦截,访问失败。

在 CORS 规范中,跨域请求主要分为两种:简单请求(simple request)和非简单请求(not-so-simple request)。

简单请求

简单请求必须符合以下四个条件,实际开发中我们一般只关注前面两个条件:

(1)使用 GET、POST、HEAD 其中一种方法;

(2)只使用了如下的安全请求头部,不得人为设置其他请求头部:

  • Accept

  • Accept-Language

  • Content-Language

Content-Type 仅限以下三种:

  • text/plain

  • multipart/form-data

  • application/x-www-form-urlencoded

(3)请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器,XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问;

(4)请求中没有使用 ReadableStream 对象。

不符合以上任一条件的请求就是非简单请求。浏览器对于简单请求和非简单请求,处理的方式也不一样。

对于简单请求,浏览器会直接发出 CORS 请求。具体来说,就是在请求头信息中,自动地增加一个Origin (来源)字段。

Origin 的值中,包含请求协议、域名和端口三个部分,用于说明本次请求来自哪个源。服务器可以根据这个值,决定是否同意这次请求。例如下面的请求头报文:


如果 Origin 指定的源不在服务器允许范围内,服务器会返回响应一个正常的 HTTP,浏览器发现回应头部中,如果没有包含 Access-Control-Allow-Origin 字段,就会抛出错误。需要注意的是,这种错误无法通过状态码识别,HTTP 响应的状态码有可能是 200。

如果 Origin 指定的源在允许范围内的话,响应头部中,就会有以下几个字段:


大家可能也看出来了一个特点,与 CORS 请求相关的字段,都以 Access-Control- 开头。

如果跨域请求是被允许的,那么响应头部中是必须有 Access-Control-Allow-Origin 头部的。它的值要么是请求时 Origin 字段的值,要么是一个 *,表示接受任意域名的请求。

Access-Control-Allow-Credentials 是一个可选字段,它的值是一个布尔值,表示是否允许发送Cookie。如果发起跨域请求时,设置了 withCredentials 标志为 true,浏览器在发起跨域请求时,也会同时向服务器发送 cookie。如果服务器端的响应中不存在 Access-Control-Allow-Credentials 头部,浏览器就不会响应内容。

特别需要说明的是,如果请求端设置了 withCredentials ,Access-Control-Allow-Origin 的值就必须是具体的域名值,而不能设置为 *,否则浏览器也会抛出跨域错误。

Access-Control-Expose-Headers 也是一个可选头部。当进行跨域请求时,XMLHttpRequest 对象的 getResponseHeader()方法只能拿到 6 个基本响应字段:

  • Cache-Control

  • Content-Language

  • Content-Type

  • Expires

  • Last-Modified

  • Pragma

而如果开发者需要获取其他响应头部字段,或者一些自定义响应头部,服务器就可以通过设置 Access-Control-Expose-Headers 头部来指定发起端可访问的响应头部。

非简单请求

非简单请求往往是对服务器有特殊要求的请求,比如请求方法为 PUT 或 DELETE,或者 Content-Type 字段类型是 application/json。

对于非简单请求的 CORS 请求,浏览器会在正式发起跨域请求之前,增加一次 HTTP 查询请求,我们称为预检请求(preflight)。浏览器会先询问服务器,当前的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 请求方法和请求头部字段。只有得到肯定答复,浏览器才会发出正式的跨域请求,否则就会报错。

比方说我们使用代码发起一个跨域请求:


浏览器会发现这是一个非简单请求,它会自动发送一个 OPTIONS 的预检请求,其中核心内容有两部分,Access-Control-Request-Method 表示后面的跨域请求需要用到的方法,Access-Control-Request-Headers 表示后面的跨域请求头内会有该内容。


服务器收到预检请求后,检查这些特殊的请求方法和头自己能否接受,如果接受,会在响应头部中包含如下信息:


上面的 HTTP 响应中,关键的是 Access-Control-Allow-Origin 字段,* 表示同意任意跨源请求都可以请求数据。部分字段我们在简单请求中解释过了,这里挑几个需要注意的头部解释一下。

  • Access-Control-Allow-Methods,这是个不可缺少的字段,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。

  • Access-Control-Allow-Headers 字段为一个逗号分隔的字符串,表明服务器支持的所有请求头部信息字段,不限于浏览器在预检中请求的字段。

  • Access-Control-Max-Age:该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是 1 天(86400 秒),在此期间,不用再发出另一条预检请求。

又拍云 CORS 配置

以上就是对 CORS 的一个简单介绍。如果您使用了又拍云的 CDN 或者云存储服务, 在访问中遇到跨域问题,是可以非常快速便捷的进行 CORS 配置的。

登陆服务控制台,依次进入:服务管理 > 功能配置 > 访问控制 > CORS 跨域共享,【管理】按钮即可开始配置。如下图所示:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

相信您看完本篇文章,对配置界面的各个字段都不再陌生啦。

推荐阅读

网络安全(一):常见的网络威胁及防范

【白话科普】从“熊猫烧香”聊聊计算机病毒

最后,Linux 基金会具备成熟的社区治理和社区运营经验,这将帮助 PyTorch 得到更广泛的应用和更好的发展。

PyTorch 基金会的成立,将给 PyTorch 带来更广泛的影响力和更广阔的想象空间,甚至有望成为类似 K8S 一样的工业界默认标准。随之而来的是,国内的几大机器学习框架的生存空间受到更大的挤压,迎来了更大的挑战。是不是可以采取一些类似的竞和手段来避免重复投入? 这也是我作为国内 AI 从事者希望看到的。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

谭中意

第四范式架构师,LF AI & Data TAC 成员,PaddlePaddle 首部官方中文书作者,星策社区发起人。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

介绍

dbVisitor 是一个全功能数据库访问 ORM 工具,提供对象映射、丰富的类型处理、动态 SQL、存储过程、 内置分页方言 20+、 支持嵌套事务、多数据源、条件构造器、INSERT 策略、多语句 / 多结果。并兼容 Spring 及 MyBatis 用法。 它不依赖任何其它框架,因此可以很方便的和任意一个框架整合在一起使用。

依赖 

 

修复​

  • 修复 Mapper模式下,未指定 namespace 时,space 为 null,导致Map.containsKey 空指针异常。
  • 指定 namespace 时,在执行时 dynamicId 截取错误。

感谢 tomato0228 的贡献。

相关链接

官方网站:https://www.dbvisitor.net/
源码地址:https://gitee.com/zycgit/dbvisitor
Spring Boot 整合手册,https://www.dbvisitor.net/docs/integration/with-springboot
快速上手:https://www.dbvisitor.net/docs/guides/quickstart

 

2023年1月26日,Apache 软件基金会(ASF)官方宣布 Apache bRPC 正式毕业,成为 Apache 顶级项目(TLP)。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

 

 

 

 

 

 

 

 

 

以上截图来自Apache官网

Apache官网原文链接:https://news.apache.org/foundation/entry/the-apache-software-foundation-announces-new-top-level-project-apache-brpc

Apache bRPC是由百度初始创立并持续贡献的工业级别RPC开源项目,在2018年正式贡献给 Apache 软件基金会进行项目孵化,2022年12月24日经过 Apache 董事会集体投票表决,Apache bRPC 项目顺利毕业,成为 Apache 软件基金会顶级项目(TLP),这是百度继 ECharts 和 Doris 之后,又一里程碑式的开源项目,也是百度长期坚持和践行开源理念的重要里程碑。

  关于 Apache bRPC

bRPC于2014年诞生于百度基础架构部,用C++编写的工业级RPC框架,常用于搜索、存储、机器学习、广告、推荐等高性能系统。2017年正式在 GitHub 进行开源,并于2018年11月正式捐献给全球顶级开源社区 Apache 软件基金会(ASF),对外开源版本的名称为 Apache bRPC,成为 ASF 孵化级项目。

一路走来,bRPC以功能全、可扩展、高性能等特性得到越来越多用户的认可和使用,经过四年多的孵化,bRPC开发者数量增长数倍、在GitHub上的Star数也超过14.4K,目前已覆盖了互联网、人工智能、搜索、推荐、电商和教育等多个行业和领域,被百度、爱奇艺、作业帮、字节跳动、京东、拼多多、滴滴、B站、vivo、小红书、第四范式、欢聚时代、shopee等公司广泛使用并对该项目进行持续贡献,线上服务实例数已超过600W,现已成为业界广受欢迎的开源RPC框架之一。

  Apache bRPC 成长史

  • 2014年,baidu-rpc在百度基础架构部诞生

  • 2016年,baidu-rpc在百度得到大规模落地和实践

  • 2017年,bRPC在GitHub上正式开源

  • 2018年,百度将 bRPC 捐献给 Apache 软件基金会并命名为 Apache bRPC,进入孵化器

  • 2021年,bRPC社区发布第一个正式版本 1.0.0

  • 2022年,正式完成商标捐赠,推动 Apache bRPC 完成毕业,成为 Apache 软件基金会顶级项目(TLP)

截至2023年1月,Apache bRPC 已在GitHub上获得14.4K Stars ,拥有超过130名贡献者,成为国内最活跃的开源社区之一,并于2022年12月获得《2022 中国开源项目社区健康案例》奖项。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

以上截图来自开源中国官网

  毕业寄语(按姓氏首字母排序)

在这个激动人心的时刻我们也收到了各界人士发来的美好寄语:

祝贺Apache bRPC顺利毕业!自bRPC开源以来,凭借其优越的性能,丰富的功能,详细的文档,迅速成为C++后台开发最流行的框架之一,特别在搜索,推荐,广告,数据库,机器学习等性能,延迟敏感的业务场景,bRPC能够帮助工程师快速搭建起各种高性能的服务。开源以来,社区一直保持高度活跃,吸引着来自不同公司的开发者们持续的完善和丰富bRPC。感谢所有的社区贡献者,期待项目未来取得更大的成功。

蔡道进

Apache bRPC PMC

~ ~ ~ ~ ~ ~

恭喜 Apache bRPC 顺利毕业,Apache bRPC不仅为包括Apache Doris在内的许多软件和企业提供了一个工业级高性能RPC框架,而且还为开发人员提供了一个很好的RPC学习平台,提供了详细的使用和原理文档。

陈明雨

Apache Doris VP

~ ~ ~ ~ ~ ~

bRPC卓越的性能、优质的文档、高质量的代码,使我感受到度厂的工程师技术水准。因此在当年毕业选择offer的时候,毫不犹豫的去了度厂打工。希望bRPC毕业后,继续快速迭代,增加更多令人惊艳的feature。

邓鑫

程序员

~ ~ ~ ~ ~ ~

很高兴看到bRPC顺利毕业,祝贺Apache bRPC社区!我很自豪ASF有一个很有前途的高性能、工业级RPC框架,期待Apache bRPC社区更加繁荣!

冯嘉

Apache bRPC Mentor

Apache ShardingSphere PMC

~ ~ ~ ~ ~ ~

时间过得真快,转眼就到了23年初,在社区小伙伴的齐心协作下,bRPC也终于从Apache毕业为顶级项目啦!一个项目的价值主要来自其承担的责任,每当bRPC被一个新用户使用或关注时,它便增加了一些责任、一份价值。作为项目成员,我们要做的就是把用户的关切转化为项目前进的每一个改进和特性。在新的一年中,bRPC需要建立更多的连接,承担更多的责任,也祝愿大家在新的一年中越来越好!

戈君

Apache bRPC VP

~ ~ ~ ~ ~ ~

恭喜Apache bRPC项目顺利毕业!工作之后非常幸运的能够参与和见证这一顶级项目的毕业过程,bRPC凭其优秀的架构设计,简洁的代码逻辑,丰富的设计文档和当时代差级的性能优势迅速成为这一领域内顶尖的C++ RPC框架,深受广大后端工程师喜爱,本人也是在其中收获良多,希望bRPC在毕业之后有更好的发展,在新的时代在新的场景下激发出更大的价值!

胡希国

Apache bRPC Committer

~ ~ ~ ~ ~ ~

恭喜Apache bRPC顺利毕业!bRPC作为高性能的C++ RPC框架,被广泛用在了各种业务场景中,其不仅具有优异的性能、详尽的文档、丰富的工具,并且兼容大量的RPC协议,使用户可以轻易地将bRPC应用至自己的系统中,获得显著的性能提升。非常荣幸参与其中,祝愿bRPC项目蓬勃发展,帮助到更多的企业和用户!

李磊

Apache bRPC PMC

~ ~ ~ ~ ~ ~

祝贺bRPC从Apache孵化器毕业,作为百度捐赠的第三个TLP项目,bRPC已经在行业中得到广泛应用,并形成了一个健康的开发者社区,为其持续发展提供了良好的基础。祝贺所有参与bRPC项目的同学,并期待你们在未来产生更大的影响,通过技术让复杂的世界变得更简单。

李涛

百度OSPO主任

~ ~ ~ ~ ~ ~

热烈祝贺Apache bRPC项目顺利毕业,成为第三个由百度捐献给Apache软件基金会的顶级项目(TLP),这是百度长期坚持和践行开源理念的重要里程碑。毕业不是终点,而是一个新的起点,百度也会持续投入,一如既往的关心和支持Apache bRPC项目的发展,也期待更多的开发者加入社区,共建开源,共享成果,共同构建一个更加多和繁荣的社区,实现社区生态和开发者互利共赢,最后衷心祝愿Apache bRPC项目和社区能越来越好!

刘帅

Apache bRPC Committer

~ ~ ~ ~ ~ ~

祝贺bRPC顺利毕业,RPC框架是分布式系统的基石,一款优秀的RPC框架产品能极大的帮助分布式系统的建设和优化,在BaikalDB的研发工作中,bRPC以稳健的性能表现几乎不用额外的关注,同时更是一个性能优化工作的工作台,以丰富的诊断能力有效提升了各项优化工作的效率。

刘涛

百度主任研发架构师

~ ~ ~ ~ ~ ~

祝贺 Apache bRPC 顺利毕业,希望 bRPC 发展越来越好!bRPC不仅代码优秀文档也同样出彩。对于想要学习高性能编码的人来说很有益处,代码值得反复学习。

陆沉

程序员

~ ~ ~ ~ ~ ~

恭喜Apache bRPC顺利毕业,成为Apache顶级项目,很荣幸见证这个时刻。入门以来,bRPC优秀的架构设计,精简的代码逻辑和丰富的设计文档让我收益颇多,更难能可贵的是bRPC社区对于新生场景的持续优化实践和探索。终点亦是起点,希望bRPC毕业后,吸引更多同学参与进来,持续反馈社区,共同进步。

卢祚

程序员

~ ~ ~ ~ ~ ~

作为bRPC社区的Mentor,很高兴能看到它成为Apache的顶级项目!他们对开源和RPC技术充满热情,使这个项目和社区进入了毕业阶段并拥有一个繁荣的未来。期待bRPC社区的取得更大的进步。

潘娟

SphereEx co-founder&CTO

Apache bRPC Mentor

Apache ShardingSphere PMC

~ ~ ~ ~ ~ ~

祝贺 Apache bRPC 顺利毕业,希望 bRPC 发展越来越好!bRPC 在拥有卓越性能的同时,还提供了高质量的代码与优质的项目文档。就我个人而言,bRPC 是我学习与成长路上如宝库一般存在的项目,里面有着诸多让我惊艳的设计。

覃庆林

程序员

~ ~ ~ ~ ~ ~

Apache bRPC项目终于毕业了!首先这说明这个项目的质量过硬,能解决现实的技术问题,同时有很好的文档和很好的代码质量;其次说明这个项目背后的团队,深有开源情怀,能够坚持下去。尤其欣喜的看到创始人戈君仍然发挥着关键作用,作为VP领导项目毕业。毕业又是一个新的起点,恭喜bRPC项目毕业成为顶级项目,希望更多人使用它。

谭中意

ASF Member

Apache bRPC PMC

~ ~ ~ ~ ~ ~

恭喜bRPC从Apache孵化器毕业。自bRPC开源以来,bRPC已经成为国内C++后台中最流行的RPC框架。很多企业使用bRPC快速完成了高性能的后台服务搭建,比如在机器学习大量应用的搜索、广告以及推荐系统中,这类系统对耗时十分敏感。借助bRPC使得工程师们可以把更多时间精力花在策略效果的迭代上,为业务的飞速发展打下坚实的基础。bRPC良好的设计,也启发了很多项目,在一些没有直接使用bRPC的企业的闭源项目中,也都能看到bRPC的影子。此外bRPC丰富的文档,也是许多后台程序员学习成长的宝库。

希望越来越多的C++工程师能参与到bRPC的开源项目中来,代表个人或者团队提交代码,将更丰富的能力、各类优化实践或者bug修复回馈给社区,促进bRPC项目走向更大的繁荣。

王维

知乎博主:果冻虾仁

Apache bRPC Committer

~ ~ ~ ~ ~ ~

祝贺Apache bRPC项目顺利毕业!感谢团队和所有社区贡献者所做的贡献。期待该项目继续取得成功,并对行业产生积极影响。

王伟冰

Apache bRPC PMC

~ ~ ~ ~ ~ ~

恭喜 Apache bRPC 顺利毕业成为 Apache 顶级项目,有幸参与,与有荣焉。期待有更多的人能够参与其中,乐在其中,并从中受益。毕业不是终点,而是新的起点,期待社区能够持续发展,越走越远。

王晓峰

Apache bRPC Committer

~ ~ ~ ~ ~ ~

祝贺顺利毕业,bRPC功能丰富,性能强大,清晰的文档能指导工程师快速搭建服务。对于无论是想学习高性能服务设计还是打算重构服务的rd来说,bRPC都是一个非常好的选择。希望bRPC能够越来越繁荣。

许大海

程序员

~ ~ ~ ~ ~ ~

祝贺Apache bRPC 顺利毕业,成为Apache 顶级项目。bRPC 是我在学习过程中很喜欢的RPC框架,也是我们社区产品所在用的RPC,拥有强大多样的功能,性能也是业界一流。希望未来可以发展越来越好,为更多业内产品提供更好的性能。感谢社区开发者的不懈努力。

杨小凡

Apache bRPC Contributor

~ ~ ~ ~ ~ ~

恭喜 Apache bRPC 毕业成为 Apache 顶级项目。Apache bRPC 配置简单,内置 HTTP、profile、var 非常好用。感谢社区的贡献者,期待社区更加繁荣。

杨勇强

SelectDB cofounder & VP

Apache Doris PMC

~ ~ ~ ~ ~ ~

bRPC 是我接触的第一款企业级rpc框架,也是工作以来参与的几个项目的工作基础。得益于清晰的设计、干净的代码、丰富的文档、友善的开发人员,让我很快上手并开始构建自己的应用,并逐渐了解了一些内部实现,同时也学到很多编程知识。总的来说,bRPC 就像一座宝库。

张正宇

程序员

~ ~ ~ ~ ~ ~

很高兴能看到 bRPC 在 Apache 孵化器顺利毕业,这离不开团队和社区的努力。bRPC 的使用场景从开源至今在稳步增加和拓展,社区开发者的数量也在持续增加,慢慢形成了良性发展的社区。期待在未来探索更多场景,让 bRPC 发展更好。

朱佳顺

Apache bRPC PMC

  特别感谢

Apache bRPC 能顺利毕业成为顶级项目(TLP),背后离不开很多人的卓越贡献,首先要感谢百度最初的捐赠以及对该项目的持续投入;同时要感谢Apache bRPC社区所有的贡献者、PMC 及孵化器导师;最后还要真诚感谢 bRPC 的所有用户,你们的持续使用与宝贵建议,是 bRPC 持续向前发展的“源动力”。

Apache bRPC 社区官方链接

Apache bRPC官方网站

https://brpc.apache.org/

Apache bRPC GitHub

https://github.com/apache/brpc

Apache bRPC 开发者邮件组

dev@brpc.apache.org

订阅 Apache bRPC 邮件列表

发送任意主题和内容到 dev-subscribe@brpc.apache.org,根据回复完成订阅

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

欢迎扫码关注 Apache bRPC 官方微信公众号
关注后,回复 “进群”,加入Apache bRPC用户交流群。
相关阅读:
  • Apache官网bRPC毕业文章:
    https://news.apache.org/foundation/entry/the-apache-software-foundation-announces-new-top-level-project-apache-brpc

  • Apache bRPC官方微信公众号毕业文章:
    https://sigusoft.com/s/A90N7PaUwB_tm7HvyDgyZw

ORM Bee Sharding 分库分表就是那么简单, 对开发透明,不影响业务,简单易用,文件小,性能好支持 Mongodb支持 JDBC还支持 Android 和 Harmony

Bee,互联网新时代的 Java ORM 工具,更快、更简单、更自动,开发速度快,运行快,更智能

V2.0.2.5(2023·宵节)
23)update(T,T)更新内部实现
24)Desensitize 支持不用知道结束位置 @Desensitize(start=0, size=-1, mask=”*”)
0 -> *
25)分片支持:=,in,between;其中in支持Number,List,Set
不参与分片:not in, not between,>=,<=。
26)完善HintManager,可只指定dataSourceName,或可只指定tableName
建议两者都指定,或至少指定tableName
27)HintManager可使用简称HM

 

V2.0.x 其它特性,请阅读:

https://www.oschina.net/news/

https://www.oschina.net/news//bee-2-0-1-22-released

更多实例,请参考 Bee-exam 实例工程:

https://gitee.com/automvc/bee-exam

感谢网友 Jade

———————————————————————

Bee 是一个简单,易用,功能强大,开发速度快,编码少的 JAVA ORM 框架。连接,事务都可以由 Bee 框架负责管理. Bee 简化了与 DB 交互的编码工作量,是 编码复杂度 为 O(1) 的 Java 框架!

Bee 简单易用:单表操作、多表关联操作,可以不用写 sql, 极少语句就可以完成 SQL 操作;概念简单 ,10 分钟即可入门。
Bee 功能强大:复杂查询也支持向对象方式,分页查询性能更高,一级缓存即可支持个性化优化;具有分布式特性。高级要求,还可以方便自定义 SQL 语句

下期功能预告:

Bee V2.0同步更新Maven.

你还想添加什么功能,请到评论区告诉我们!

码云上的项目首页:

https://gitee.com/automvc/bee

https://gitee.com/automvc/bee-springboot

github:

https://github.com/automvc/bee

Vesta 是一款实用、方便的镜像扫描以及 Docker、Kubernetes 基线安全检查工具。 致力检查因 Docker 或 Kubernetes 错误配置而导致的各种潜在安全问题的发生。

Vesta v1.0.4 更新内容如下:

新功能

  • 增加sidecar中Env以及EnvFrom中变量检查,并且定位到具体的ConfigMap或Secret
  • 增加Pod annotation检测
  • 增加供应链投毒检测

改进

  • 更改了的rpm检测的方法
  • 更改了containerd内核检测方法
  • upgrade命令更换为update

vesta 收集了网上用量最多的包名字以及目前已知的恶意包名字,与容器中已安装的包进行相似度对比,相似度大于80%即判断为可疑的投毒包(目前仅支持python的检测,后期将加入其他语言的检测以及镜像投毒检测)

Crossplane 是一个构建云原生控制平面的框架,不需要编写代码。它有一个高度可扩展的后端,使你能够建立一个控制平面,可以协调应用程序和基础设施;以及一个高度可配置的前端,让你控制它提供的声明性 API 的模式。

v1.11.0 版本是一个定期的季度版本,包括许多令人兴奋的功能,这些功能是 Crossplane 社区强烈要求的,如 Composition Functions、EnvironmentConfig,以及将 CompositionRevisions 提升到 beta 版本。

此外,这个 v1.11.0 版本还包括根据 Crossplane 用户的直接反馈而重写的主要文档,并且还着重于稳定性修复等内容。

新功能

  • 在 alpha 版本中引入的 Composition Function 支持,现在可以用你选择的任何编程语言编写自己的自定义组合逻辑,以增强 Crossplane 的内置修补和转换功能
  • 在 alpha 中引入了 EnvironmentConfig 支持,现在可以通过使用一般运行时环境的配置数据来修补 Composition 中的资源,而不是局限于单个组合资源中的信息。
  • 将 CompositionRevisions 提升至 v1beta1,并默认启用。CompositionRevisions 已经根据社区的反馈进行了改进,现在已经稳定下来,可以在生产中普遍使用。
  • Crossplane 文档网站经过重新设计,为 Crossplane 的用户提供了更好的体验,无论他们是刚接触该项目还是更高级的用户。

值得注意的更新

  • 这将是最后一个发布到 Docker Hub 的版本,未来的版本将使用 xpkg.upbound.io 代替
  • ControllerConfing API 已被弃用
  • Lock API v1alpha1 已被弃用
  • CompositionRevisions 的名称在构建时加入了部分哈希后缀

其他变化:

  • 为文档添加新的步骤
  • 添加对 deleteCompositePolicy 的支持
  • 在 CI 中验证文档内容并支持单指令本地开发
  • 用新的软件包仓库和搜索链接来更新文档
  • 更新 crossplane 图表的 README.md
  • ……

更多详情可查看:https://github.com/crossplane/crossplane/releases/tag/v1.11.0

OpenTTD 是 Microprose 发行的运输大亨豪华版 (TTD) 的开源版。玩家扮演新成立的运输公司老板,通过建设铁路、公路、桥梁、机场、车站等设施,运输旅客、货物和各种自然资源的模拟经营游戏。游戏最终目标是通过运输赚取最大利润,经过残酷的竞争,最终打败对手,成为运输大亨。

目前 OpenTTD 已发布最新的 13.0 版本,这个大型版本具有众多功能和改进,涵盖用户界面、游戏功能以及 NewGRF 和游戏脚本模组扩展。

  • 可变界面缩放至任何大小(不仅仅是 2 倍和 4 倍),带有可选的厚实斜角,在使用 HiDPI 或混合 DPI 设置时可更好地进行自动缩放。
  • 从新游戏窗口可直接访问 NewGRF/AI/GS 设置。
  • 对几个窗口进行了各种小调整和改进。
  • NewGRFs 提供在购买列表中分层显示的引擎变体
  • 多轨道平交道口,以防止道路车辆停在道口中间
  • GameScripts 的自定义排行榜
  • 新增越往下游越宽的天然河流

除了这些功能和改进之外,此版本还修复了许多错误。以下为此版本的相关链接:

  • 下载
  • 变更日志

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

phpBB 3.3.10 已发布,代号“The Way of Bertie”。该版本是 3.3.x 分支的维护版本,改进了对 PHP 8.2 的支持,并解决了之前版本中反馈的多个问题。

phpBB 是开源的 PHP 论坛建站系统,支持 MySQL、PostgreSQL、MSSQL、SQLite 与 Oracle 等数据库。

由于 Emoji CDN 的服务被关闭,旧版本的 phpBB 会在浏览器的后备 emoji 旁边显示”broken image”图标。为了解决此问题,emoji CDN 已与其他修复一起被替换,其中包括改进了使用 Spamhaus 阻止列表时的错误处理,以及在 Moderator Control Panel (MCP) 中添加反馈时正确处理 emoji。

除此之外,开发团队还改进了对可能无法访问主域的国家/地区使用 reCAPTCHA 的支持,并改进了允许“使用第三方 CDN”的 ACP 设置的说明。

其他变化包括进一步强化 cron 重定向,以防止未处理异常。

开发团队还提到,由于最近对 GitHub 上的 phpBB 仓库进行了调整,在 GitHub Codespaces 的支持下,为 phpBB 做贡献变得比以往任何时候都容易,详情。

下载地址:https://www.phpbb.com/downloads/

详情查看发布公告。

Masonry 是一个 Rust GUI 框架,其作者最近刚发布了 0.1 版本,并提出了对 Rust UI 的愿景,他称之为”Fearless GUI”,具备以下特点:

  • 可迭代
  • 具备灵活性
  • 可测试
  • 可观测
  • 可重用

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

最新发布的 Masonry 0.1 旨在实现上述目标,目前提供了用于创建窗口的平台(使用 Glazier 作为后端),每个窗口都包含一个 Widget 树。它还提供了用于在 runtime 检测 Widget 树的工具,可编写单测试,方便开发者调试和维护应用程序。

基于 Masonry,开发者可实现即时模式 (immediate-mode) GUI、Elm 架构、函数式响应 GUI。

示例代码

 

发布公告

作者:京东零售 王雷

背景

云原生下的流水线是通过启动容器来运行具体的功能步骤,每次运行流水线可能会被调度到不同的计算节点上。这会导致一个问题:容器运行完是不会保存数据的,每当流水线重新运行时,等等。在云原生场景下,不存在,大大延长了流水线运行时间,浪费很多不必要的时间、网络和计算成本。

在许多流水线场景中,同一条流水线的多次执行之间是有关联的。如果能够用到上一次的执行结果,则可以大幅缩短执行时间。为了提高用户使用流水线的体验,我们加入支持缓存的功能,挂接远程储存管理构建缓存,可以实现同一个项目的编译依赖复用,在同一条流水线的多次运行中,共享同一份缓存。

目标

通过实现云原生流水线的缓存技术,实现代码编译的缓存复用,平均加速流水线3~5倍;

实现方案

我们将需要进行缓存的文件,使用zstd的方式进行压缩,通过远程挂载cfs,将构建的缓存持久化到cfs上的指定位置。当下一次构建开始的时候,判断缓存是否被命中,如果命中缓存,我们从cfs上的指定位置pull对应的缓存压缩包,解压到相应目录下。

所用工具-cfs+zstd

非用户自定义镜像,将需要的工具打到引擎的基础镜像中,作为所有镜像的基础工具。

用户自定义镜像,不和用户镜像进行强绑定,如果需要使用缓存功能,可以使用Restore缓存原子和Save缓存原子,设置缓存key和缓存目录,实现缓存功能。

1 cfs远程挂载

•将工具和启动脚本,配置文件打到基础镜像

•在开启缓存的位置,启动脚本,开始挂载cfs


2 zstd压缩

针对现有的几种压缩方式进行了性能对比,最后选用了zstd进行压缩。

Zstd,全称 Zstandard,是 Facebook 于 2016 年开源的新无损压缩算法。Zstd 还可以以压缩速度为代价提供更强的压缩比,速度与压缩率的比重可通过增量进行配置。与 zlib、lz4、xz 等当前流行的压缩算法不同,Zstd 寻求一种压缩性能与压缩率通吃的方案,而实际上它也确实做到了。在由官方所列出的表格中,可以看到,Zstd 不仅具备优秀的压缩性能,在压缩率上也有非常亮眼的表现。在过去的两年里,Linux内核、HTTP协议、以及一系列的大数据工具(包括Hadoop 3.0.0,HBase 2.0.0,Spark 2.3.0,Kafka 2.1.0)等都已经加入了对zstd的支持。

常见的压缩算法性能对比:

1.png

压缩包大小对比:

依赖包的大小 465M 压缩效率 tar压缩 423M 14s左右 zstd压缩 205M 1s左右

缓存的实现

我们借鉴了github cache action,zadig,gitlab等缓存的处理方式,同时结合服务自身的特点

将整体分成三步

•检查是否命中缓存:根据缓存key,判断缓存是否命中

缓存key 缓存的唯一标识 不同语言编译原子 根据下载代码的代码库地址自动获取 设置的缓存key:home_auth/home-auth-center 用户自定义镜像 自定义缓存key

•pull缓存

当缓存命中后,根据缓存路径,找到挂载到cfs上的缓存压缩包,解压到指定的缓存目录下

•push缓存:将依赖包进行压缩,放到cfs的挂载目录下

2.png

依赖包的大小 465M tar压缩 423M zstd压缩 205M

3.png

缓存的使用限制和回收策略

使用限制

目前存储缓存数没有限制,存储库中所有缓存的总大小限制是根据申请的cfs的大小限制:20G。

回收策略

我们会删除7天内未被访问的任何缓存。利用etcd的watch机制,实现缓存的回收。

etcd可以 指定的键、前缀目录的更改,并对更改时间进行通知。BASE引擎中,缓存的清除策略借助etcd来实现。

缓存过期策略:在编译加速的实现中,每个需要缓存的项目都有对应的缓存key,通过etcd监控key,并且设置过期时间,例如7天,如果在7天之内再次命中key,则通过lease进行续约;7天之内key都没有被使用,key就会过期删除,通过监听对应的前缀,在过期删除的时候,调用删除缓存的方法。


不同技术栈的最佳实践

1 Java

以Maven构建工具为例,其默认配置文件位于conf/settings.xml文件中,默认指定环境变量$M2_HOME来设置缓存目录,这样同一条流水线多次执行可以复用 ${M2_HOME}/.m2 目录 (缓存目录),甚至同一个应用下的多个分支之间都可以使用同一个缓存目录,就像本地构建一样。

 BASE执行 无缓存 平均时间:5.26min 有缓存 平均时间:41.462s 提升效率 提升87.3% 缓存命中率 接近100%

2 NodeJs

在nodejs编译中,我们的缓存目录是当前用户空间,针对node_modules文件进行压缩打包,push到cfs;如果缓存命中,从cfs上pull并且解压到当前用户空间下,恢复缓存。

使用举例

 BASE执行 无缓存 平均时间:58s 有缓存 平均时间:29s 提升效率 提升50% 缓存命中率 接近100%

3 Golang编译

Golang 缓存路径通过环境变量控制,将的内容压缩成zstd的包,上传到cfs的指定路径下。pull缓存的时候,拉取到对应的

 BASE执行 无缓存 平均时间:117s 有缓存 平均时间:18s 提升效率 提升84.6% 缓存命中率 接近100%

4 GCC编译

我们使用ccache进行缓存实现。ccache(“compilercache”的缩写)是一个编译器缓存,该工具会高速缓存编译生成的信息,并在编译的特定部分使用高速缓存的信息。ccache的缓存目录:CCACHE_DIR,我们将这个目录下的文件进行压缩,push到cfs,当第二次运行并且命中缓存,从cfs上pull并解压到CCACHE_DIR指定的目录下。

总结

在不同语言的编译原子内部,默认开启缓存的设置。第一次运行流水线的时候,会进行依赖的下载,第二次运行流水线,会命中缓存,无需进行依赖的下载,提高了流水线执行的效率。缓存默认保存7天。

自定义镜像进行缓存的最佳实践

为了满足用户使用自定义镜像的方式触发流水线,我们增加了两个通用的缓存原子。

Restore缓存:恢复缓存

Save缓存:保存缓存

4.png

在编译之前,添加Restore缓存原子

5.png

在编译之后,添加Save缓存原子

6.png

使用举例

在maven编译原子中,默认开启了maven编译的缓存;同时还有nodejs的编译构建,所以我们增加了restore原子和save原子

7.png

 BASE执行 无缓存 平均时间:21min57s 其中maven: 17min83s nodejs: 4min19s 有缓存 平均时间:4min20s 其中maven: 1min10s nodejs: 2min36s 缓存效率提升 maven: 93.7% nodejs:39.8%(nodejs编译中有包含单测试) 缓存命中率 接近100%

未来规划

•不同编译原子,向用户开放配置,如是否开启缓存,设置缓存key

•实现不同语言编译原子增量push缓存功能

Nostr 是基于加密密钥对 (Cryptographic Keypairs) 的去中心化网络,没有采用 P2P (peer-to-peer) 技术。该协议非常简单,且可扩展。

Nostr 全称是 Notes and Other Stuff Transmitted by Relays,可以理解为:通过中继设备传输笔记和其他东西。有人认为,Nostr 之于社交网络,就像 HTTP 之于信息或 IMAP 之于通信。虽然目前 Nostr 的主要用处是打造类似 Twitter 的(去中心化)社交网络,但它是一个底层级别的协议,几乎可以在其上构建任何你喜欢的东西,可能性无穷无尽。

协议构成

  • Nostr 包含两个角色,分别是 client 和 relay。client 是用户社交的客户端,relay 是转发服务器。
  • 用户无需注册,只需要一个密钥对(公钥+私钥)即可使用,然后把要发的信息做签名,发送给 relays
  • 关注者从 relays 上订阅信息

技术细节摘要

  • 技术实现上,nostr 使用 websocket + JSON 的方式。其中主要包括以下指令
    • Client 到 Relay 主要是通过以下指令:
      • 。发出事件,可以扩展出很多很多的动作来,比如:发信息,删信息,迁移信息,建 Channel ……扩展性很好。
      • 。用于请求事件和订阅更新。收到消息后,relay 会查询其内部数据库并返回与过滤器匹配的事件,然后存储该过滤器,并将其接收的所有未来事件再次发送到同一 websocket,直到 websocket 关闭。
      • 。用于停止被  请求的订阅。
    • Relay 到 Client 主要是通过以下指令:
      • 。用于发送客户端请求的事件。
      • 。用于向客户端发送人类可读的错误消息或其他信息
  • 关于  下面是几个常用的基本事件:
    • : :比如,用户名,用户头像,用户简介等这样的信息。
    • : :用户要发的信息内容
    •  :用户想要推荐给关注者的Relay的URL(例如)

运行原理

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

自从马斯克接手 Twitter 以来,Twitter 为了 “开源节流” 进行了大刀阔斧的改革,Twitter Blue 会员服务一改再改、为了大幅缩减开支裁员 50%、之后为了保证广告收入禁止第三方开发类 Twitter 应用、再之后砍掉免费 API 并推出付费计划。

这些改革有没有为 Twitter 创造价值我们不得而知,但却得罪了不少用户和开发者。尤其是在 API 方面,Twitter 以 “莫须有的罪名” 禁止了包括 Tweetbot、Twitterrific 等应用使用其 API,导致大量用户无法使用第三方应用。面对这种 “阴晴不定” 的老板和平台,不少品牌、机构和知名人物都纷纷逃离 Twitter,入驻了 Mastodon —— 一个基于 ActivityPub 协议创建的网络,允许其他人加入或建立自己的服务器以参与和查看彼此的内容。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如今为了防止用户流失,阻止用户转用 Mastodon,Twitter 已禁止 Movetodon 这个迁移工具使用其 API。

为了帮助用户能够从 Twitter 快速迁移到 Mastodon,不少开发者都推出了一些有用的工具和服务。Movetodon 就是这样一种工具,可以帮助那些已经迁移到 Mastodon 的用户找到他们之前在 Twitter 上关注的人。

近日 Movetodon 的开发者 Tibor Martini 在 Mastodon 上发帖表示:

你可能已经注意到,https://movetodon.org/ 的 Twitter 登录目前无法使用。根据 Twitter 的说法,该应用 “违反了 Twitter 的规则和政策”。由于他们提到的电子邮件从未到达我的收件箱,所以目前我无法知道更多。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Twitter 给出的理由是 Movetodon 违反了 Twitter 的规则和政策,这个措辞跟之前禁止 Tweetbot 和 Twitterrific 的理由保持一致,很可能 Movetodon 实际上根本就没有违反任何政策(当初在禁止 Tweetbot 之时,Twitter 也没有相关规则和政策,是事后才新增的)。

虽然 Twitter 已经明确表示不欢迎第三方客户端,但 Movetodon 明显并不属于这个范畴,而且 Twitter 宣布计划终止对其 API 的免费访问,但生效时间是 2 月 9 日,Movetodon 显然也不应该受到影响。

这么看来,一切违背 Twitter “利益” 的行为,即便符合政策,也都会被官方禁止。纵观过往,Movetodon 可能也不会是最后一个受害者。

据外媒 techcrunch 报道,近日 Penpot 再获得 1200 万美 A+ 轮融资。与去年 9 月获得的 800 万美 A 轮融资相同,新一轮仍由思科附属的风险投资公司 Decibel 领投。

Penpot 是第一个面向跨域团队的开源设计和原型设计平台,使用开放的 Web 标准 (SVG),且基于 Web ,不依赖操作系统,有浏览器即可使用。

与被 Adobe 收购的 Figma 等设计平台相比,开源的 Penpot 具有极高的灵活性,既可以将其用作基于云的 SaaS,也可以使用源代码将其托管在本地开发环境中。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在去年融资 A 轮时,Penpot 拥有约 15000 star 和 10 万用户。而目前最新数据是 2 万 Srars + 25 万名活跃用户,用户中包含 10000+ 家公司,包括谷歌、微软、红帽、腾讯、字节跳动和 Mozilla 等。

这笔融资的时间刚好赶上 Penpot 新发布的 Beta 版本, 1 月 31 日新发布的 Penpot Beta 版本包含新的“Flex Layout”功能,可用于在 CSS 中轻松构建响应式布局。此外还允许用户利用浏览器内存将协作项目的内存缓存提高到 16 GB(行业标准限制是 2 GB) ,同时提供更好的代码检查、更灵活地为项目添加临时贡献者等功能。这些额外功能都是免费的,因为该公司尚未推出任何类型的付费功能或服务。

在接受采访时, Penpot 的 CEO 兼联合创始人 Pablo Ruiz-Múzquiz 表示,融资的一部分会用于构建更多可在云、自托管和本地环境中使用的附加工具和功能上,且所有新功能都是免费的,Penot 短期内没有任何对服务或功能收费的计划,其投资者也完全不关注短期内的收入。下一步工作的重点是如何提高该平台的易用性,使 Penpot 平台的使用门槛更低,进而吸引更多设计师和开发者。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

▲ Penpot 创始团队,右下是创始人 Pablo Ruiz-Múzquiz

Techcrunch 的报道已获得  Penpot 的 CEO 兼联合创始人 Pablo Ruiz-Múzquiz  证实。

谷歌首席执行官桑德尔·皮查伊 (Sundar Pichai) 今天宣布,他们将在未来几周内面向公众推出由 LaMDA 提供支持的实验性对话式 AI 服务,称为 Bard —— 与当前流行的 ChatGPT 展开直接竞争。在公开发布之前,目前 Bard 仅开放给受信任的测试人员。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Bard 由谷歌的大型语言模型 LaMDA(对话应用语言模型)提供支持,该服务能在获得简单提示的情况下生成详细答案,比如午餐做什么。上周有媒体报道称,谷歌正在员工中测试 Bard 的部分功能,这是其应对流行聊天机器人 ChatGPT “红色代码”计划的一部分。Bard 的功能包括名为“Apprentice Bard”的聊天机器人,以及可以以问答形式使用的新搜索桌面设计。

Sundar Pichai 表示:“很快,你就会在搜索中看到 AI 支持的功能,它可以将复杂的信息和多个视角的信息提炼成易于理解的格式,这样你就可以迅速了解全部知识,并从网络上学到更多。”

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

谷歌介绍了一个使用 Bard 来简化复杂主题的例子,比如向 9 岁的孩子解释 NASA James Webb 太空望远镜的新发现。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

除了发布 Bard,谷歌还允许开发者利用其语言模型来创建自己的 AI 聊天程序。Sundar Pichai 表示,他们将于下个月开始向公司、个人开发者和创作者开放其生成语言 API。他在博客中写道:“除了我们自己的产品外,我们认为重要的是,通过在我们最好的模型之上进行构建,让其他人能够轻松、安全、可扩展地从这些进步中受益。随着时间的推移,我们打算创建一套工具和 API,让其他人可以轻松地使用 AI 构建更具创新性的应用程序。”

Pichai 强调,他希望谷歌的人工智能服务“大胆而负责 (Bold and responsible)”,但没有详细说明如何阻止 Bard 分享有害或滥用内容。

TIOBE 公布了 2023 年 2 月的编程语言排行榜

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

总的来说,本月 TIOBE 指数变化不大。在获得 2022 年度编程语言之后,C++ 仍然保持着远远领先于其他编程语言的势头,目前的同比增幅为 5.93%。涨幅第二的是 C 语言,但只有 1% 左右的增长。

或许是受最近越来越多有关该指数质疑的影响,TIOBE CEO Paul Jansen 在本月榜单中进行了解释称,其“重点在于每一种编程语言都有自己的优势和劣势,且通常在某些领域表现突出”。并以榜单前 20 名中的两种新的蓬勃发展的语言 Scratch 和 Rust 进行了举例:Scratch 是一款少儿编程学习工具,在中小学中很流行;Rust 则是面向专家的安全高性能编程语言,两者服务于不同的目的。

Scratch 用来学习编程的,在中小学很流行,而 Rust 是面向专家的安全高性能编程语言。换句话说,它们服务于不同的目的。排名前 4 的语言也是如此。 Python 非常适合数据挖掘、AI 编程、统计程序、研究项目、网站、小型粘合程序和学习如何编程。C 语言是编写小型、嵌入式、安全关键和高性能程序的最佳语言。C++ 是在满足对 C 语言的需求上,用来编写大型软件系统的最佳选择。Java 则是最适合业务应用程序的后端和为 Android 编写应用程序。

TIOBE 2 月 TOP 20 编程语言 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

本月 Top 20 列表中出现变动的编程语言有:

  • Go 的排名从 #12 上升至 #11
  • R 语言的排名从 #13 上升至 #12
  • Matlab 的排名从 #15 上升至 #13
  • Delphi/Object Pascal 的排名从 #17 上升至 #14
  • Swift 的排名从 #11 跌至 #15
  • Perl 的排名从 #19 上升至 #17
  • Scratch 的排名从 #20 上升至 #18
  • Classic Visual Basic 的排名从 #14 跌至 #19
  • Rust 的排名从 #18 跌至 #20

TOP 10 编程语言 TIOBE 指数走势(2002-2022)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

第 21-50 名编程语言排行

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

第 51-100 名如下,由于它们之间的数值差异较小,仅以文本形式列出(按字母排序):

ActionScript, Apex, AutoHotkey, B4X, bc, BlitzMax, Bourne shell, C shell, Chapel, Clojure, Common Lisp, Crystal, Eiffel, Elixir, Erlang, Forth, GAMS, Hack, IDL, Inform, Io, Ioke, J#, JScript, Korn shell, LabVIEW, Ladder Logic, Limbo, LPC, MQL5, NATURAL, OCaml, OpenCL, OpenEdge ABL, PL/I, Processing, Programming Without Coding Technology, Q, Raku, REXX, S, Smalltalk, Solidity, SPARK, Stata, VBScript, VHDL, X++, XC, Zig

TIOBE 编程社区指数(The TIOBE Programming Community index)是一个衡量编程语言受欢迎程度的指标,该指数每月更新一次。评判的依据来自世界范围内的工程师、课程和第三方供应商,包括流行的搜索引擎,如 Google、必应、雅虎、维基百科、亚马逊、YouTube 和百度都被用于指数计算。值得注意的是,TIOBE 指数并不代表编程语言的好坏或编写代码的多少。

该指数可以用来检查你的编程技能是否还能跟上时代的步伐,或者在开始建立一个新的软件系统时,基于指数对采用何种编程语言做出决策。

TIOBE 指数的定义方式,以及详细榜单信息均可查看官网。

摘要:本文介绍将TensorFlow网络模型迁移到昇腾AI平台,并执行训练的全流程。然后以TensorFlow 1.15训练脚本为例,详细介绍了自动迁移、手工迁移以及模型训练的操作步骤。

本文分享自华为云社区《将TensorFlow模型快速迁移到昇腾平台》,作者:昇腾CANN。

当前业界很多训练脚本是基于TensorFlow的Python API进行开发的,默认运行在CPU/GPU/TPU上,为了使这些脚本能够利用昇腾AI处理器的强大算力执行训练,需要对TensorFlow的训练脚本进行迁移。

首先,我们了解下模型迁移的全流程:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

通过上图可以看出,模型迁移包括“脚本迁移 –> 模型训练 –> 精度调优 –> 性能调优 –> 模型固化”几个流程,其中:

  • “脚本迁移”是将TensorFlow训练脚本经过少量修改,可以运行在昇腾AI处理器上。
  • “模型训练”是根据模型参数进行多轮次的训练迭代,并在训练过程中评估模型准确度,达到一定阈值后停止训练,并保存训练好的模型。
  • “精度调优”与“性能调优”是在用户对精度或性能有要求时需要执行的操作。
  • “模型固化”是将训练好的、精度性能达标的模型固化为pb模型。

下面我们针对“脚本迁移”和“模型训练”两个阶段进行详细的介绍。

脚本迁移

将TensorFlow训练脚本迁移到昇腾平台有自动迁移和手工迁移两种方式。

  • 自动迁移:算法工程师通过迁移工具,可自动分析出原生的TensorFlow Python API在昇腾AI处理器上的支持度情况,同时将原生的TensorFlow训练脚本自动迁移成昇腾AI处理器支持的脚本,对于少量无法自动迁移的API,可以参考工具输出的迁移报告,对训练脚本进行相应的适配修改。
  • 手工迁移:算法工程师需要参考文档人工分析TensorFlow训练脚本的API支持度,并进行相应API的修改,以支持在昇腾AI处理器上执行训练,该种方式相对复杂,建议优先使用自动迁移方式。

下面以TensorFlow 1.15的训练脚本为例,讲述训练脚本的详细迁移操作,TensorFlow 2.6的迁移操作类似,详细的迁移点可参见“昇腾文档中心[1]”。

自动迁移

自动迁移的流程示意图如下所示:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

详细步骤如下;

1. 安装迁移工具依赖。


2. 执行自动迁移命令。

进入迁移工具所在目录,例如“tfplugin安装目录/tfplugin/latest/python/site-packages/npu_bridge/convert_tf2npu/”,执行类似如下命令可同时完成脚本扫描和自动迁移:


其中main.py是迁移工具入口脚本,-i指定待迁移原始脚本路径,-r指定迁移报告存储路径。

3. 查看迁移报告。

在/root/models/official/output_npu_*下查看迁移后的脚本,在root/models/official/report_npu_*下查看迁移报告。

迁移报告示例如下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

手工迁移

手工迁移训练脚本主要包括如下迁移点:

1. 导入NPU库文件。


2. 将部分TensorFlow接口迁移成NPU接口。

例如,修改基于Horovod开发的分布式训练脚本,使能昇腾AI处理器的分布式训练。


修改后:


3. 通过配置关闭TensorFlow与NPU冲突的功能。

关闭TensorFlow中的remapping、xla等功能,避免与NPU中相关功能冲突。例如:


4. 配置NPU相关参数

Ascend平台提供了功能调试、性能/精度调优等功能,用户可通过配置使能相关功能,例如enable_dump_debug配置,支持以下取值:

  • True:开启溢出检测功能。
  • False:关闭溢出检测功能。

配置示例:


模型训练

迁移成功后的脚本可在昇腾AI处理器上执行单Device训练,也可以在多个Device上执行分布式训练。

单Device训练

1)配置训练进程启动依赖的环境变量。


2)执行训练脚本拉起训练进程。


分布式训练

分布式训练需要先配置参与训练的昇腾AI处理器的资源信息,然后再拉起训练进程。当前有两种配置资源信息的方式:通过配置文件(即ranktable文件)或者通过环境变量的方式。下面以配置文件的方式介绍分布式训练的操作。

1)准备配置文件。

配置文件(即ranktable文件)为json格式,示例如下:


2)执行分布式训练。

依次设置环境变量配置集群参数,并拉起训练进程。

拉起训练进程0:


拉起训练进程1:


以上就是TensorFlow模型迁移训练的相关知识点,您也可以在“昇腾社区在线课程[2]”板块学习视频课程,学习过程中的任何疑问,都可以在“昇腾论坛[3]”互动交流!

相关参考:

[1]昇腾文档中心https://www.hiascend.com/zh/document

[2]昇腾社区在线课程https://www.hiascend.com/zh/edu/courses

[3]昇腾论坛https://www.hiascend.com/forum

 

 

关注,第一时间了解华为云新鲜技术~

摘要:JVM参数分为三类:标准参数、非标准参数(-X参数)和高级选项(-XX参数)。本文主要为大家讲解-X参数和-XX参数。

本文分享自华为云社区《JVM运行参数之-X和-XX参数》,作者:共饮一杯无 。

JVM参数分为三类:标准参数、非标准参数(-X参数)和高级选项(-XX参数)。本文主要为大家讲解-X参数和-XX参数。

-X参数

JVM的-X参数是非标准参数,在不同版本的jvm中,参数可能会有所不同,可以通过java -X查看非标准参数。


运行模式-Xint、-Xcomp、-Xmixed

  • 在解释模式(interpreted mode)下,-Xint标记会强制JVM执行所有的字节码,当然这会降低运行速度,通常低10倍或更多。
  • -Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。
    • 然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的少,原因是-xcomp没有让JVM启用JIT编译器的全部功能。JIT编译器可以对是否需要编译做判断,如果所有代码都进行编译的话,对于一些只执行一次的代码就没有意义了。
  • -Xmixed是混合模式,将解释模式与编译模式进行混合使用,由jvm自己决定,这是jvm默认的模式,也是推荐使用的模式。

示例:强制设置运行模式


-XX参数

-XX参数也是非标准参数,主要用于JVM的调优和debug操作。
-XX参数的使用有2种方式,一种是boolean类型,一种是非boolean类型

  • boolean类型

格式:-XX:[±]
如:-XX:+DisableExplicitGC 表示禁用手动调用gc操作,也就是说调用System.gc()无效

  • 非boolean类型

格式:-XX:
如:-XX:NewRatio=2 表示新生代和老年代的比值,表示新生代占1,老年代占2。则新生代占整个堆的1/3。

用法:


-Xms与-Xmx参数(设置jvm的堆内存的初始大小和最大大小)

-Xms与-Xmx分别是设置jvm的堆内存的初始大小和最大大小。
-Xmx2048m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。
-Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。 适当的调整jvm的内存大小,可以充分利用服务器资源,让程序跑的更快。示例:


 

关注,第一时间了解华为云新鲜技术~

世界技术圈在发生什么?

云原生的演进

图片

这里跟大家一起回顾一下张磊老师在云原生开发者日上关于“云原生技术演进”的分享。

有很多人会问,是不是云原生就等于K8s这些开源项目?其实今天出现的这些开源项目如K8s、docker、istio、dapr,是一些概念与方法论的一种技术实现,他们的背后就是云原生的理论体系,比如不可变的基础设施,高自动化、自愈自运维,语言和架构无关,高可扩展等等,而我们现在在实践的微服务、容器化、sidecar等就是为了支撑这些概念和方法论的技术和架构实现。这里有一条逻辑链路,就是当有一套概念和方法论之后,就会出现对应的技术和架构,我们在开源社区里就会出现相应的开源实现。

举个例子,容器化的技术架构对应的开源实现就有Docker、K8s这样的开源项目。用户端体现的这些开源项目,他其实实践的就是一套技术架构,而在这套技术架构背后的理论思想就是我们说的概念和方法论。整个云原生生态的体现就是这么一套方法论加架构加开源技术的这么一个集合,他的目的就是希望让云计算技术很好的去服务我们的开发者,目标就是帮助开发者降本增效,而云的一些特质就可以帮助我们去实现这一目标,比如云是无限弹性的,快速的资源交付,还可以按量付费等。

为了让云的这些特征能够最终帮助开发者降本增效,我们就需要这套逻辑链路来达成这个目标,这也是现阶段云原生技术角度来看一个非常自然的演进路线。

图片

除了技术角度之外,我们还可以从时间维度来看云原生的演进过程。其实开发者希望得到的能力和基础设施平台能够提供的能力之间是有一道很大的鸿沟,开发者要的多,平台给得少,云计算实际上一直在解决这个问题。

时间线越往前,基础设施越弱,但开发者的诉求其实一直在增长,软件越写越复杂,彼此之间的鸿沟会越来越大,这时就会需要有人去填补这个鸿沟。在2010年以前,我相信大家都有听说过ESB这样的传统中间件的解决方案,中间件顾名思义就是填补在基础设施和开发者之间鸿沟的一套系统,它的能力非常强,可以满足开发者开发大型软件的需求。

随着时间推移,云计算技术越来越成熟,能力越来越丰富,有很多的需求可以用云的能力直接提供,所有陆续会出现一些比如PaaS这样的平台,其实就是云计算提供的中间件能力。到了2014之后,随着容器和K8s这样的技术出现,我们能在云计算平台拿到更多的能力,这是一种非常强大的平台层的抽象,我们前面讲过的不可变基础设施等都是通过容器、K8s技术实现的,之前需要花很多资源和精力搭建的中间件的能力,现在开发者可以非常容易的获取和实践,从此开发者的诉求和基础设施之间的鸿沟不断的在变小。

随着时间推移,2020年之后,云平台甚至已经开始提供中间件的核心能力,比如流量治理,他其实是service mesh的一个核心功能,而Dapr的出现,他进一步的把更多中间件能力,包括我们的微服务开发,服务发现、工作流、服务调用等,将这些能力下沉到了K8s,进一步的填补了鸿沟。从时间维度我们可以预测,未来云平台的能力会越来越强,甚至会超出开发者的诉求,云计算的关注点慢慢会从基础设施的这些运维时,越来越多的向开发时上移。

所以,不管是从技术角度还是时间角度来看,云原生的核心关注点正在发生变化,他已经渗透到了我们应用开发的各个环节,这就意味着会在某一个时刻,当云能力足够多的时候,必然要去关注我们开发者真正的开发过程。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

开源软件的崛起

软件正在吞噬世界,而开源正在吞噬软件,拥抱开源是这个时代的开发者应该具备的思维和能力,而拥抱开源能够让每一位开发者站在巨人的肩膀上,快速实现业务价值。而开源社区活跃着最优秀、最有活力的开发者,开源项目替代商用软件是必然趋势。而云原生技术催生的开源软件同时解决了企业卡脖子的问题,不被某一家云厂商所绑定。

图片

我们发现,开源软件已经无孔不入,在原有的商用软件的各个领域都有开源软件的替代,开源软件正在崛起。所以我们毅然决然的选择开源我们的MASA Stack及MASA的系列产品。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

为什么选择开源?

1. 丰富.NET的开源生态,为.NET技术生态做出我们应有的贡献 2. 希望全世界的.NET开发者能够评审我们的代码,要求我们更开放、更规范、更严谨 3. 也希望.NET开发者能够参与进来,社区驱动,让产品更健壮,更有未来

战略技术趋势

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

下面我们来看一下权威机构Gartner发布的2023年战略技术趋势,以上10个技术趋势我们来关注一下数字免疫系统、应用可观测性、自适应AI和平台工程。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

平台工程

图片

不管是DevOps还是AIOps,各种Ops解决的就是将开发和运维达成有机运转的协作状态,是非常不错的方法论,但每个组织的落地却参差不齐,并不理想,导致开发人员需要直面苦涩的K8s等基础架构的知识体系。

平台工程是将复杂的基础设施能力通过平台的方式整合并形成自助式的开发者门户,目标是优化开发者体验并加快产品团队为客户创造价值的速度,让变化更简单。让运维人员更加关注开发人员的交付体验、应用服务的安全性和稳定性,开发人员不再感知基础设施,更加关注业务实现。平台工程是云原生技术运维时到开发时的产品形态。

Gartner预测,到2026年,80%的软件工程组织将建立平台团队,其中75%将包含开发者自助服务门户。自MASA Stack诞生以来,我们的产品定位就是企业级云原生技术底座,方便大家理解我们加上了一个PaaS的补充说明,Gartner在合适的时间给了我们一个合适的叫法,那就是平台工程,我们今天正式把MASA Stack定位为平台工程!

可观测性

图片

数字化时代的核心标志是数据驱动智能运营与商业创新,而拥有应用可观测性使企业够利用他们数据驱动决策来获得竞争优势。它能够在正确的时间提供正确数据,从而使企业在不确定的时代快速响应,让变化更简单。可观测性是MASA Stack的核心能力之一,我们在每个版本会持续迭代增强。

自适应AI

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

现阶段AI技术已经融入到企业生产作业的方方面面,如自然语言处理、机器视觉、流程自动化、智能推荐、分析预测等技术被应用到了像RPA数字员工、舆情监控、预测性维护、客户画像、商品推荐、机器人客服等场景。自适应AI是通过不断反复训练模型,在运行和开发环境中不断的使用新的数据进行学习,从而实现敏捷运营,快速自适应。更多的企业正在尝试用AI代替人去做重复性、低难度的工作,让员工去做更有创造力的工作,实现企业愿景,获得员工个人价值实现。

数字免疫系统

图片

76%负责数字产品的团队需要对营收负责,企业需要一个能在实现高商业价值的同时,降低风险和提高客户满意度的方法,数字免疫系统能满足这一要求。

数字免疫系统通过结合数据驱动的可观测性、AI增强测试、混沌工程、自动修复,SRE,软件供应链安全等技术手段来提高系统的弹性和稳定性。

Gartner预测,到2025年,投资建设数字免疫系统的企业机构将能够减少多达80%的系统宕机时间,所减少的损失将直接转化为更高的收入。从某种层面上来说,平台工程、应用可观测性和自适应AI直接促成了数字免疫系统的实现。

应用现代化

如何应对不确定性

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

国内外市场多重不确定性对企业持续增长提出考验,不确定性时代最大的特点是变化,客户需求在变、技术潮流在变,要想跟上变化,就需要拥有实时洞察和快速响应个性化、场景化、定制化需求的平台能力,打造可组装模块化应用的能力,用组装式的应用架构来呼应组装式的业务架构。

企业首先需要拥有一套无边界的平台底座,也就是数字底座,再将已有的信息化系统进行中台化、服务化重构,构建领域服务群,结合第三方生态及行业解决方案,最终打造统一的企业自有的数字化平台,这是数字化转型的必要路径。第一步需要攻克的难题,就是要将老旧的系统进行现代化升级,那么什么是应用现代化呢?

应用现代化

图片

IDC的2022中国云计算市场预测中,应用现代化位列第一,到2024年,大多数遗留应用将实现一定程度的现代化投资。55%的应用将使用云服务来扩展功能或替换低效代码。应用现代化也已成为一种共识,华为云认为应用现代化是以软件的敏捷交付为导向,实现贯穿基础设施到应用的认知重塑、架构升级和技术跃迁。

AWS认为应用现代化是采用最新技术构建,是开发组织加快创新、提高性能、安全性和可靠性,同时降低总拥有成本的解决方案。微软云认为应用现代化是通过使用具有松散耦合微服务、托管数据库、Al、DevOps 支持和内置监控的云原生架构来快速创新。

IBM认为应用现代化是对现有旧应用(单体、本地、瀑布式开发) 的平台基础架构、内部架构和功能进行现代化(云原生、微服务、DevOps) 改造的过程。应用现代化是数字化转型的必备能力,是应用开发的新范式。

关于我们

图片

但很少有人关心.NET应用现代化的解决方案,我们MASA就此诞生了,MASA就是现代化应用和服务架构的意思,我们致力于用.NET技术赋能开发者,使用MASA Stack及MASA的系列开源解决方案帮助企业对老旧的应用进行现代化改造,帮助企业.NET技术团队拥抱云原生,平滑的升级技术架构和知识体系,直接帮助企业降低数字化转型门槛,帮助企业快速试错,快速创新,应对不确定性,让变化更简单!

一站式解决方案

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

相比JAVA成熟的开源技术生态,.NET开源生态的现状确实有点不如人意,于是我们决定提供前端、后端、平台工程一站式的应用现代化解决方案。

MASA Blazor

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在前端我们基于Material Design打造了企业级多端组件库MASA Blazor,使用.NET实现全栈解决方案,具有模块化、响应式和优秀的性能,搭配MAUI使用在移动端、桌面端都有极佳的效果。

MASA Framework

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在后端我们提供了微服务开发框架MASA Framework,我们把他定义为.NET下一代微服务开发框架,内嵌分布式运行时——Dapr云原生最佳实践,能够快速实现分布式、微服务、DDD、SaaS等现代化应用开发。我们参考Dapr的优秀设计,提供了20项Building Blocks,还有MASA Stack各项能力的SDK支持。MASA Framework在2022年开办了公开课,已经出了6期的课程,有兴趣的朋友可以关注进来。

MASA Stack

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

最后就是我们的核心开源产品MASA Stack,MASA Stack是开源企业级开发者门户——平台工程,包含企业IT现代化应用开发交付的全部板块,如应用治理、服务编排与集成、数据开发与治理、可观测性、DevOps研发协作、AI智能等一站式解决方案。MASA Stack 1.0发版的同时,我们会一并发布MASA Blazor和MASA Framework的1.0版本。

愿景

图片

我们再来聊聊我们的愿景,我们MASA希望在影响力上成为.NET技术生态中Spring的存在,成为.NET现代应用开发的标配。MASA Framework可以比肩Spring boot,MASA Stack 可以比肩Spring Cloud,但我们不仅仅只是比肩,我们还能超越!

MASA Stack 1.0 发布会——趋势篇.pdf扫码观看回放

图片


如果你对我们的开源项目感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们 图片

使用 HertzBeat 对 线程池框架 DynamicTp 进行监控实践!

线程池框架 DynamicTp 介绍

DynamicTp 是Jvm语言的基于配置中心的轻量级动态线程池,内置监控告警功能,可通过SPI自定义扩展实现。

  • 支持对运行中线程池参数的动态修改,实时生效。
  • 实时监控线程池的运行状态,触发设置的报警策略时报警,报警信息推送办公平台。
  • 定时采集线程池指标数据,配合像 grafana 这种可视化监控平台做大盘监控。

HertzBeat 介绍

HertzBeat 是一款开源,易用友好的实时监控系统,无需Agent,拥有强大自定义监控能力。

  • 支持对应用服务,数据库,操作系统,中间件,云原生等监控,阈值告警,告警通知(邮件微信钉钉飞书短信 Slack Discord Telegram)。
  • 其将Http,Jmx,Ssh,Snmp,Jdbc等协议规范可配置化,只需配置YML就能使用这些协议去自定义采集任何您想要采集的指标。您相信只需配置YML就能立刻适配一个K8s或Docker等新的监控类型吗?
  • HertzBeat 的强大自定义,多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。

在 HertzBeat 5分钟搞定监控 DynamicTp

操作前提,您已拥有 DynamicTp 环境和 HertzBeat 环境。

  • DynamicTp 集成接入文档
  • HertzBeat 部署安装文档

一. 在 DynamicTp 端暴露出指标接口 ,它将提供 metrics 接口数据。

  1. 开启 SpringBoot Actuator Endpoint 暴露出指标接口

  1. 重启后测试访问指标接口 是否有响应json数据如下:

二. 在 HertzBeat 监控页面添加 DynamicTp 线程池监控

  1. 新增 DynamicTp 监控

路径:菜单 -> 中间件监控 -> DynamicTp监控 -> 新增DynamicTp监控

monitor-dynamic-tp-1.png

  1. 配置监控 DynamicTp 所需参数

在监控页面填写 DynamicTp 服务IP监控端口(默认8080),最后确定添加即可。
其他参数如采集间隔超时时间等可以参考帮助文档 https://hertzbeat.com/docs/help/dynamic_tp/

monitor-dynamic-tp-2.png

  1. 完成✅,现在我们已经添加好对 DynamicTp 的监控了,查看监控列表即可看到我们的添加项。

monitor-dynamic-tp-1.png

  1. 监控列表项的操作->监控详情图标 即可浏览 DynamicTp线程池 的实时监控指标数据。

monitor-dynamic-tp-3.png

  1. 监控历史详情TAB 即可浏览 DynamicTp线程池 的历史监控指标数据图表📈。

monitor-dynamic-tp-4.png

monitor-dynamic-tp-5.png

DONE!完成啦!通过上面几步,总结起来其实也就只用两步

  • 第一步暴露 DynamicTp 端端点
  • 第二步在 HertzBeat 监控页面配置IP端口添加监控即可

通过上面的两步我们就完成了对 DynamicTp 的监控,我们可以在 HertzBeat 随时查看监控详情指标信息来观测其服务状态。 当然只是看肯定是不完美的,监控往往伴随着告警阈值,当 DynamicTp 的线程池指标超出我们的期望值或异常时,能及时的通知到我们对应的负责人,负责人收到通知处理问题,这样才是一个完整的监控告警流程。

接下来我们就来一步一步演示如何配置 HertzBeat 系统里的阈值告警通知,让 DynamicTp线程池 的指标异常时,及时通知给我们

三. 在 HertzBeat 系统添加 DynamicTp线程池 指标阈值告警

  1. 对某个重要指标配置告警阈值

路径:菜单 -> 告警阈值 -> 新增阈值

  • 选择配置的指标对象,DynamicTp监控主要是一些线程池相关指标,我们举例对 -> 这个指标进行阈值设置, 当线程运行超时数量大于1时发出告警。
  • 这里我们就配置当此指标 的 时发出告警,告警级别为严重告警,三次即触发,具体如下图。

monitor-dynamic-tp-6.png

  1. 新增消息通知接收人

配置接收人,让告警消息知道要发给谁,用什么方式发。

路径:菜单 -> 告警通知 -> 告警接收人 -> 新增接收人

消息通知方式支持 邮件,钉钉,企业微信,飞书,WebHook,短信等,我们这里以常用的钉钉为例。

  • 参照此帮助文档 https://hertzbeat.com/docs/help/alert_dingtalk 在钉钉端配置机器人,设置安全自定义关键词,获取对应值。
  • 在 HertzBeat 配置接收人参数如下。

【告警通知】->【新增接收人】 ->【选择钉钉机器人通知方式】->【设置钉钉机器人ACCESS_TOKEN】-> 【确定】

alert-notice-1.png

  1. 配置关联的告警通知策略⚠️ 【新增通知策略】-> 【将刚设置的接收人关联】-> 【确定】

配置告警通知策略,让告警消息与接收人绑定,这样就能决定哪些告警发给哪个人。

alert-notice-2.png

完毕,现在坐等告警消息过来啦。叮叮叮叮


小结

这篇实践文章带我们体验了如何使用 HertzBeat 监控 DynamicTp线程池 指标数据,可以发现集 的 HertzBeat 在操作与使用方面更加的便捷,只需页面上简单点一点就能把 DynamicTp线程池 纳入监控并告警通知,再也不需要部署多个组件写YML配置文件那些繁琐操作了。

DynamicTp Github: https://github.com/dromara/dynamic-tp
HertzBeat Github: https://github.com/dromara/hertzbeat

欢迎了解使用Star支持哦!

只需要一条docker命令即可安装体验heartbeat :

作者: 京东零售 陈震

一、 什么是Backbone

在前端的发展道路中,前端框架老之一jQuery对繁琐的DOM操作进行了封装,提供了链式调用、各类选择器,屏蔽了不同浏览器写法的差异性,但是前端开发过程中依然存在作用域污染、代码复用度低、冗余度高、数据和事件绑定烦琐等痛点。

5年后,Backbone横空出世,通过与Underscore、Require、Handlebar的整合,提供了一个轻量和友好的前端开发解决方案,其诸多设计思想对于后续的现代化前端框架发展起到了举足轻重的作用,堪称现代前端框架的基石。

通过对Backbone前端框架的学习,让我们领略其独特的设计思想。



二、 核心架构

按照MVC框架的定义,MVC是用来将应用程序分为三个主要逻辑组件的架构模式:模型,视图和控制器。这些组件被用来处理一个面向应用的特定开发。 MVC是最常用的行业标准的Web开发框架,以创建可扩展的项目之一。 Backbone.js为复杂WEB应用程序提供模型(models)、集合(collections)、视图(views)的结构。

◦ 其中模型用于绑定键值数据,并通过RESRful JSON接口连接到应用程序;

◦ 视图用于UI界面渲染,可以声明自定义事件,通过监听模型和集合的变化执行相应的回调(如执行渲染)。



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



如图所示,当用户与视图层产生交互时,控制层监听变化,负责与数据层进行数据交互,触发数据Change事件,从而通知视图层重新渲染,以实现UI界面更新。更进一步,当数据层发生变化时,由Backbone提供了数据层和服务器数据共享同步的能力。

其设计思想主要包含以下几点:

◦数据绑定(依赖渲染模板引擎)、事件驱动(依赖Events)

◦视图组件化,并且组件有了生命周期的概念

◦前端路由配置化,实现页面局部刷新

这些创新的思想,在现代前端框架中进一步得到了继承和发扬。



三、 部分源码解析

Backbone极度轻量,编译后仅有几kb,贯穿其中的是大量的设计模式:工厂模式、观察者模式、迭代器模式、适配器模式……,代码流畅、实现过程比较优雅。按照功能拆分为了Events、Model、Collection、Router、History、View等若干模块,这里摘取了部分精彩源码进行了解析,相信对我们的日常代码开发也有一定指导作用:

(1)迭代器

EventsApi起到一个迭代器分流的作用,对多个事件进行解析拆分,设计的非常经典,执行时以下用法都是合法的:

◦用法一:传入一个名称和回调函数的对象


◦用法二:使用空格分割的多个事件名称绑定到同一个回调函数上


实现如下:


(2)监听器

用于一个对象监听另外一个对象的事件,例如,在A对象上监听在B对象上发生的事件,并且执行A的回调函数:


实际上这个功能用B对象来监听也可以实现:


这么做的好处是,方便对A创建、销毁逻辑的代码聚合,并且对B的侵入程度较小。实现如下:


(3)Model值set

通过option-flags兼容赋值、更新、删除等操作,这么做的好处是融合公共逻辑,简化代码逻辑和对外暴露api。实现如下:


四、 不足(对比react、vue)

对比现代前端框架,由于Backbone本身比较轻量,对一些内容细节处理不够细腻,主要体现在:

◦视图和数据的交互关系需要自己分类编写逻辑,需要编写较多的监听器

◦监听器数量较大,需要手动销毁,维护成本较高

◦视图树的二次渲染仅能实现组件整体替换,并非增量更新,存在性能损失

◦路由切换需要自己处理页面更新逻辑



五、为什么选择Backbone

看到这里,你可能有些疑问,既然Backbone存在这些缺陷,那么现在学习Backbone还有什么意义呢?

首先,对于服务端开发人员,Backbone底层依赖underscore/lodash、jQuery/Zepto,目前依然有很多基于Jquery和Velocity的项目需要维护,会jQuery就会Backbone,学习成本低;通过Backbone能够学习用数据去驱动View更新,优化jQuery的写法;Backbone面对对象编程,符合Java开发习惯。

其次,对于前端开发人员,能够学习其模块化封装库类函数,提升编程技艺。Backbone的组件化开发,和现代前端框架有很多共通之处,能够深入理解其演化历史。

Skywalking是由国内开源爱好者吴晟(原OneAPM工程师,目前在华为)开源并提交到Apache孵化器的产品,它同时吸收了Zipkin/Pinpoint/CAT的设计思路,支持非侵入式埋点。是一款基于分布式跟踪的应用程序性能监控系统。另外社区还发展出了一个叫OpenTracing的组织,旨在推进调用链监控的一些规范和标准工作。

OpenTracing

近年各种调用链监控产品层出不穷,呈现百花齐放的态势,为了避免碎片化,促进互操作性,社区诞生了一个叫做OpenTracing的标准化组织。

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

如上图所示:OpenTracing旨在标准化Trace数据结构和格式,其目的是:

  • 不同语言开发的Trace客户端的互操作性,Java/.Net/PHP/Python/NodeJs等语言开发的客户端,只要遵循OpenTracing标准,就都可以对接OpenTracing兼容的监控后端。
  • Tracing监控后端的互操作性,只要遵循OpenTracing标准,企业可以根据需要替换具体的Tracing监控后端产品,比如从Zipkin替换成Jaeger/CAT/Skywalking等后端。

OpenTracing初衷和方向是好的,但是目前还不明朗,不少调用链监控产品并未明确支持OpenTracning标准。对其后续走势我们可以持续关注。

在构建监控系统时,大家往往在Metrics,Tracing和Logging几个名词和方式之间纠结。 总体说来,我们是在一些通用的名词间纠结。可以通过图表来定义监控的作用域,使各名词的作用范围更明确。比如通过维恩图(Venn diagram)来描述Metrics, tracing, logging三个概念的定义:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布) 

Metric的特点是,它是可累加的:他们具有原子性,每个都是一个逻辑计量单,或者一个时间段内的柱状图。 例如:队列的当前深度可以被定义为一个计量单,在写入或读取时被更新统计; 输入HTTP请求的数量可以被定义为一个计数器,用于简单累加; 请求的执行时间可以被定义为一个柱状图,在指定时间片上更新和统计汇总。

Logging的特点是,它描述一些离散的(不连续的)事件。 例如:应用通过一个滚动的文件输出debug或error信息,并通过日志收集系统,存储到Elasticsearch中; 审批明细信息通过Kafka,存储到数据库(BigTable)中; 又或者,特定请求的数据信息,从服务请求中剥离出来,发送给一个异常收集服务,如NewRelic。

Tracing的最大特点就是,它在单次请求的范围内,处理信息。 任何的数据、数据信息都被绑定到系统中的单个事务上。 例如:一次调用远程服务的RPC执行过程;一次实际的SQL查询语句;一次HTTP请求的业务性ID。

在OpenTracing中,有几个基本概念我们需要提前了解清楚:

1、Trace(追踪):
在广义上,一个trace代表了一个事务或者流程在(分布式)系统中的执行过程。在OpenTracing标准中,trace是多个span组成的一个有向无环图(DAG),每一个span代表trace中被命名并计时的连续性的执行片段。

2、Span(跨度):一个span代表系统中具有开始时间和执行时长的逻辑运行单。span之间通过嵌套或者顺序排列建立逻辑因果关系。

3、Logs:每个span可以进行多次Logs操作,每一次Logs操作,都需要一个带时间戳的时间名称,以及可选的任意大小的存储结构。

4、Tags:每个span可以有多个键值对(key:value)形式的Tags,Tags是没有时间戳的,支持简单的对span进行注解和补充。

其中单个Trace和各个Span之间的关系:

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

一个span可以和一个或者多个span间存在因果关系。OpenTracing定义了两种关系:ChildOf 和 FollowsFrom。这两种引用类型代表了子节点和父节点间的直接因果关系。

Skywalking可以理解为实现了OpenTracing规范,同时提供了更加现代化、酷炫的UI,供人们可以对应用更加的直观的监控。
接下来,我们将结合Skywalking的界面来了解如何查看单个Trace:

首先,在Skywalking中,官方针对Java应用封装了一个Segment概念,实质上就是Span数组的封装,为的是更好的表示Java中跨线程间的调用(后续文章将会详细讲到),因此,在Skywalking里面,一次完整的追踪所包含的数据结构应该是:
– Trace = Segment1 + Segment2 + …… + SegmentN
– 其中每个Segment所包含的数据:Segment = Span1 + Span2 + …… + SpanN

通过一张官方的截图来讲解:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图中蓝色部分是一个进程调用,代表的是Kafka/test-trace-topic/Consumer这个服务为调用入口,紧随着下面的白色长块则代表跨进程或跨线程的调用块,进去并通过浏览器查看返回的数据:

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

我们可以看到右侧有一组spans数组,数组中每一组数据中都带有traceId,segmentId,parentSegmentId,refs数组,spanId,parentSpanId,type等数据。Skywalking界面上那些层级关联关系就是根据这些数据来进行展示的,比如:

在同一个Segment中,spanId最顶层数值为-1,默认从0开始自增,依次代表层级。即Span与Span时间通过parentSpanId表示关系。Segment与Segment之间通过refs数组中的parentSegmentId表示关系

好了,其实最后一段才是我想表达的东西,顺带将整个东西理清楚记录一下,使用过程中碰到的问题会陆续记录到这里。


文章转自:https://zhuanlan.zhihu.com/p/

如有侵权,将第一时间删除文章内容。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

作者 | 一贫

导读

本文介绍了Module Federation的概念、应用场景,并结合具体的代码示例帮助大家对Module Federation的模块共享,公共依赖加载有个初步的认识,方便后续更深入的学习相关内容,同时也给微前端的探索提供一种新的思路,定会给大家一定的提升和启发。

全文5405字,预计阅读时间14分钟。

01 什么是Module Federation(MF)?

普遍直译为『模块联邦』,我们看看官网是怎么说的?

Motivation

Multiple separate builds should form a single application. These separate builds should not have dependencies between each other, so they can be developed and deployed individually. This is often known as Micro-Frontends, but is not limited to that.

多个独立的构建可以形成一个应用程序。这些独立的构建不会相互依赖,因此可以单独开发和部署它们。

这通常被称为微前端,但并不仅限于此。

通俗点讲,即MF提供了能在当前应用中远程加载其他服务器上应用的能力。对此,可以引出下面两个概念:

  • host:引用了其他应用的应用
  • remote:被其他应用所使用的应用

图片

△图片来源于网络

它与我们普遍讨论的基座应用、微应用有所不同,它是去中心化的,相互之间是平等的,每个应用是单独部署在各自的服务器,每个应用都可以引用其他应用,也能被其他应用所引用,即每个应用可以充当host的角色,亦可以作为remote出现。

图片

△图片来源于网络

02 应用场景

  • 微前端:通过shared以及exposes可以将多个应用引入同一应用中进行管理。
  • 资源复用,减少编译体积:可以将多个应用都用到的通用组件单独部署,通过MF的功能在runtime时引入到其他项目中,这样组件代码就不会编译到项目中,同时亦能满足多个项目同时使用的需求,一举两得。

03 如何使用

项目结构如下:

  • module-home:首页,在layout展示一个字符串。
  • module-layout:布局,只包含一个html模板。
  • module-lib:暴露工具方法,共享lodash库。

图片

3.1 相关配置参数一览

图片

3.2 各应用的配置


如下图所示:在layout中展示了home挂载的节点,控制台也打印了调用lib中方法的log,同时lib分享的lodash也生效了(全程只加载了一个lodash)。

图片

图片

3.3 以remoteLib为例简要分析


  • host加载自己的bundle main.js,其中使用jsonp加载对应remote提供的remoteLib.js;
  • 在remote中暴露了全局变量,host将remote注入后可以获取对应模块,其中的共享模块使用前会检查自身有没有,如果没有再去加载remote的内容。

04 拓展学习

可以学习开源项目:基于 Webpack 5 Module Federation,优雅且实用的微前端解决方案 https://github.com/yuzhanglong/mf-lite。

——END——

参考资料:

[1]How to Build a Micro Frontend with Webpack’s Module Federation Plugin

[2]Webpack 新功能 Module Federation 深入解析

[3]基于 Webpack Module Federation,这可能是一个比较优雅的微前端解决方案

[4]探索 webpack5 新特性 Module federation 在腾讯文档的应用

[5]Module Federation原理剖析

推荐阅读

巧用Golang泛型,简化代码编写

Go语言DDD实战初级篇

Diffie-Hellman密钥协商算法探究

贴吧低代码高性能规则引擎设计

浅谈权限系统在多利熊业务应用

分布式系统关键路径延迟分析实践

微服务后端开发的最大痛点之一就是调试困难,非常影响我们的开发效率。

如果我们想与其他微服务进行联动调试,则需要在本地环境中启动对应的微服务模块,这可能需要大量的配置和构建时间,同时也会占用我们本地很多资源,可能还会出现”带不动“的情况。

虽然说我们可以在测试服务器上进行调试,但整个流程也是比较漫长,提交代码 -> 触发CI/CD -> 等待构建成功,可能简单的 BUG 我们提交代码打个日志就能解决问题,当遇到复杂的 BUG 时通过这个方式在服务器上调试就非常难受了,太浪费时间了,提交 -> 等待,反反复复,始终没有本地开发工具直接调试的方便。

下面介绍的工具将远程和本地融为一体,让本地开发更加流畅。

Telepresence

Telepresence 是一个开源工具,用于在本地开发环境中模拟 Kubernetes 集群中的微服务,它允许开发人员在本地开发环境中运行和调试微服务,而不必担心环境的复杂性和配置困难。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

简单来说 Telepresence 将 Kubernetes 集群中服务的流量代理到本地,Telepresence 主要有四个服务:

Telepresence Daemon: 本地的守护进程,用于集群通信和拦截流量。

Telepresence Traffic Manager: 集群中安装的流量管理器,代理所有相关的入站和出站流量,并跟踪主动拦截。

Telepresence Traffic Agent: 拦截流量的 sidecar 容器,会注入到工作负载的 POD 中。

Ambassador Cloud: SaaS 服务,结合 Telepresence 一起使用,主要是生成预览 URL 和一些增值服务。

全局流量拦截

全局流量拦截是将 Orders 的所有流量都拦截到我们本地开发机上,如下图。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

个人流量拦截

个人流量拦截允许选择性地拦截服务的部分流量,而不会干扰其余流量。这使我们可以与团队中的其他人共享一个集群,而不会干扰他们的工作。每个开发人员都可以只针对他们的请求拦截 Orders 服务,同时共享开发环境的其余部分。

个人拦截需要配合 使用,这是一项收费服务,免费用户可以最多拦截 3 个服务。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

结合 Telepresence 开发调试 Rainbond 上的微服务

  • 基于主机安装 Rainbond 或基于 Helm 安装 Rainbond。

安装 Telepresence

MacOS:


Windows:


安装 Telepresence 流量管理器到集群中

可以使用 Telepresence 快速安装 Traffic Manager,本地需要有 kubeconfig 文件 。


或者在 Kubernetes 集群中使用 Helm 安装 Traffic Manager。

本地连接远程服务

本地使用 连接远程 Kubernetes API Server,本地需要有 kubeconfig 文件


在 Rainbond 上快速部署 Pig 微服务应用

通过 Rainbond 开源应用商店快速部署 Pig 微服务应用,部署后如下图

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

后面会以 pig-auth 这个服务为例,演示本地开发调试的流程,这里需要做一些小改动:

  1. 从应用商店安装的应用默认 Workload 是字符串,需要修改 Workload 为易于查看的,这里以 pig-auth 为例,进入组件中编辑组件名称,修改组件英文名称为

  2. 简单来说 telepresence 的工作原理就是代理 k8s service,默认 gateway 到 auth 是使用的 nacos 做的负载均衡,这样的话 telepresence 是无法拦截到流量的,我们需要修改 gateway 配置使用 k8s service 做负载均衡。

    • 打开 pig-register 组件的 8848 对外端口,访问 nacos,修改 的 , 通过 pig-auth 组件内的端口访问地址获取。
  3. 如果本地只启动一个 pig-auth 服务,pig-auth 需要连接 pig-register 和 redis,那么就需要将这俩服务的对外端口打开,并修改配置文件让本地的 pig-auth 服务可以连接远程到 pig-register 和 redis。

在本地调试 auth 服务

使用 IDEA 或 VScode 在本地启动 pig-auth 服务。

在本地使用 telepresence 拦截 pig-auth 流量,命令如下:


命令拆解:


最终命令:


我们在本地给退出登陆这块逻辑打上断点,然后通过线上的前端退出登陆,打到我们本地 IDEA上,整体效果如下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

最后

Telepresence 可以帮助我们简化本地开发流程,同时保证代码的正确性和可靠性。还能使我们在集群中轻松调试和测试代码,提高开发效率。结合 Rainbond 的部署简化,从开发到部署都非常的简单,让我们专注于代码编写。

一、Redis的特性

1.1 Redis为什么快?

  • 基于内存操作,操作不需要跟磁盘交互,单次执行很快
  • 命令执行是单线程,因为是基于内存操作,单次执行的时间快于线程切换时间,同时通信采用多路复用
  • Redis本身就是一个k-v结构,类似于hashMap,所以查询性能接近于O(1)
  • 同时redis自己底层数据结构支持,比如跳表、SDS
  • lO多路复用,单个线程中通过记录跟踪每一个sock(I/O流)的状态来管理多个I/O流

1.2 Redis其他特性

  • 更丰富的数据类型,虽然都是k、v结构,value可以存储很多的数据类型
  • 完善的内存管理机制、保证数据一致性:持久化机制、过期策略
  • 支持多种编程语言
  • 高可用,集群、保证高可用

1.3 Redis高可用

  • 很完善的内存管理机制,过期、淘汰、持久化
  • 集群模式,主从、哨兵、cluster集群

二、Redis数据类型以及使用场景

Redis的数据类型有String、Hash、Set、List、Zset、bitMap(基于String类型)、 Hyperloglog(基于String类型)、Geo(地理位置)、Streams流。

2.1 String

2.1.1 基本指令

 // 批量设置 > mset key1 value1 key2 value2 // 批量获取 > mget key1 key2 // 获取长度 > strlen key // 字符串追加内容 > append key xxx // 获取指定区间的字符 > getrange key 0 5 // 整数值递增 (递增指定的值) > incr intkey (incrby intkey 10) // 当key 存在时将覆盖 > SETEX key seconds value // 将 key 的值设为 value ,当且仅当 key 不存在。 > SETNX key value 

2.1.2 应用场景

  1. 缓存相关场景 缓存、 token(跟过期属性完美契合)
  2. 线程安全的计数场景 (软限流、分布式ID等)

2.2 Hash

2.2.1 基本指令

 // 将哈希表 key 中的域 field 的值设为 value 。 > HSET key field value // 返回哈希表 key 中给定域 field 的值。 > HGET key field // 返回哈希表 key 中的所有域。 > HKEYS key // 返回哈希表 key 中所有域的值。 > HVALS key // 为哈希表 key 中的域 field 的值加上增量 increment 。 > HINCRBY key field increment // 查看哈希表 key 中,给定域 field 是否存在。 > HEXISTS key field 

2.2.2 应用场景

  1. 存储对象类的数据(官网说的)比如一个对象下有多个字段
  2. 统计类的数据,可以对单个统计数据进行单独操作

2.3 List

存储有序的字符串列表,素可以重复。列表的最大长度为 2^32 – 1 个素(,每个列表超过 40 亿个素)。

2.3.1 基本指令

 // 将一个或多个值 value 插入到列表 key 的表头 > LPUSH key value [value ...] // 将一个或多个值 value 插入到列表 key 的表尾(最右边)。 > RPUSH key value [value ...] // 移除并返回列表 key 的头素。 > LPOP key // 移除并返回列表 key 的尾素。 > RPOP key // BLPOP 是列表的阻塞式(blocking)弹出原语。 > BLPOP key [key ...] timeout // BRPOP 是列表的阻塞式(blocking)弹出原语。 > BRPOP key [key ...] timeout // 获取指点位置素 > LINDEX key index 

2.3.2 应用场景

  1. 用户消息时间线

    因为list是有序的,所以我们可以先进先出,先进后出的列表都可以做

2.4 Set

2.4.1 基本指令

 // 将一个或多个 member 素加入到集合 key 当中,已经存在于集合的 member 素将被忽略。 > SADD key member [member ...] // 返回集合 key 中的所有成员。 > SMEMBERS key // 返回集合 key 的基数(集合中素的数量)。 > SCARD key // 如果命令执行时,只提供了 key 参数,那么返回集合中的一个随机素。 > SRANDMEMBER key [count] // 移除并返回集合中的一个随机素。 > SPOP key // 移除集合 key 中的一个或多个 member 素,不存在的 member 素会被忽略。 > SREM key member [member ...] // 判断 member 素是否集合 key 的成员。 > SISMEMBER key member // 获取前一个集合有而后面1个集合没有的 > sdiff huihuiset huihuiset1 // 获取交集 > sinter huihuiset huihuiset1 // 获取并集 > sunion huihuiset huihuiset1 

2.4.2 应用场景

  1. 抽奖 spop跟srandmember随机弹出或者获取素
  2. 点赞、签到等,sadd集合存储
  3. 交集并集 关注等场景

2.5 ZSet(SortedSet)

sorted set,有序的set,每个素有个score。

score相同时,按照key的ASCII码排序。

2.5.1 基本指令

 //将一个或多个 member 素及其 score 值加入到有序集 key 当中。 > ZADD key score member [[score member] [score member] ...] // 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递增(从小到大)来排序 > ZRANGE key start stop [WITHSCORES] // 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递减(从大到小)来排列。 > ZREVRANGE key start stop [WITHSCORES] // 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。 > ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] // 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。 > ZREM key member [member ...] // 返回有序集 key 的基数。 > ZCARD key // 为有序集 key 的成员 member 的 score 值加上增量 increment 。 > ZINCRBY key increment member // 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。 > ZCOUNT key min max // 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。 > ZRANK key member 

2.5.2 应用场景

  1. 排行榜

三、Redis的事务

3.1 事务基本操作

 // 1. multi命令开启事务,exec命令提交事务 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set k1 v1 QUEUED 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) OK // 2. 组队的过程中可以通过discard来放弃组队。 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> set k4 v4 QUEUED 127.0.0.1:6379(TX)> discard OK 

3.2 Redis事务特性

  1. 单独的隔离操作

事务中的所有命令都会序列化、按顺序地执行。

事务在执行过程中,不会被其他客户端发送来的命令请求所打断。

2. 没有隔离级别的概念

队列中的命令没有提交之前,都不会被实际地执行,因为事务提交之前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头疼的问题。

3. 不保证原子性

Redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。

四、Redis 分布式锁

4.1 Lua 实现分布式锁

 local lockSet = redis.call('exists', KEYS[1]) if lockSet == 0 then redis.call('set', KEYS[1], ARG[1]) redis.call('expire', KEYS[1], ARG[2]) end return lockSet 

五、Redis总体数据结构

5.1 Redis dict字典

5.1.1 RedisDb数据接口(server.h文件)

数据最外层的结构为RedisDb

 typedef struct redisDb { dict *dict; /* The keyspace for this DB */ //数据库的键 dict *expires; /* Timeout of keys with a timeout set */ //设置了超时时间的键 dict *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/ //客户端等待的keys dict *ready_keys; /* Blocked keys that received a PUSH */ dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */ int id; /* Database ID */ //所在数 据库ID long long avg_ttl; /* Average TTL, just for tats */ //平均TTL,仅用于统计 unsigned long expires_cursor; /* Cursor of the active expire cycle. */ list *defrag_later; /* List of key names to attempt to defrag one by one, gradually. */ } redisDb; 

5.1.2 dict数据结构(dict.h文件)

我们发现数据存储在dict中

 typedef struct dict { dictType *type; //理解为面向对象思想,为支持不同的数据类型对应dictType抽象方法,不同的数据类型可以不同实现 void *privdata; //也可不同的数据类型相关,不同类型特定函数的可选参数。 dictht ht[2]; //2个hash表,用来数据存储 2个dictht long rehashidx; /* rehashing not in progress if rehashidx == -1 */ // rehash标记 -1代表不再rehash unsigned long iterators; /* number of iterators currently running */ } dict; 

5.1.3 dictht结构(dict.h文件)

 typedef struct dictht { dictEntry table; //dictEntry 数组 unsigned long size; //数组大小 默认为4 #define DICT_HT_INITIAL_SIZE 4 unsigned long sizemask; //size-1 用来取模得到数据的下标值 unsigned long used; //改hash表中已有的节点数据 } dictht; 

5.1.4 dictEntry节点结构(dict.h文件)

 typedef struct dictEntry { void *key; //key union { void *val; uint64_t u64; int64_t s64; double d; } v; //value struct dictEntry *next; //指向下一个节点 } dictEntry; 

5.1.5 RedisObject(service.h文件)

 /* Objects encoding. Some kind of objects like Strings and Hashes can be * internally represented in multiple ways. The 'encoding' field of the object * is set to one of this fields for this object. */ #define OBJ_ENCODING_RAW 0 /* Raw representation */ #define OBJ_ENCODING_INT 1 /* Encoded as integer */ #define OBJ_ENCODING_HT 2 /* Encoded as hash table */ #define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */ #define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */ #define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */ #define OBJ_ENCODING_INTSET 6 /* Encoded as intset */ #define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */ #define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */ #define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */ #define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */ #define LRU_BITS 24 #define LRU_CLOCK_MAX ((1<<LRU_BITS)-1) /* Max value of obj->lru */ #define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */ #define OBJ_SHARED_REFCOUNT INT_MAX /* Global object never destroyed. */ #define OBJ_STATIC_REFCOUNT (INT_MAX-1) /* Object allocated in the stack. */ #define OBJ_FIRST_SPECIAL_REFCOUNT OBJ_STATIC_REFCOUNT typedef struct redisObject { unsigned type:4; //数据类型 string hash list unsigned encoding:4; //底层的数据结构 跳表 unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency * and most significant 16 bits access time). */ int refcount; //用于回收,引用计数法 void *ptr; //指向具体的数据结构的内存地址 比如 跳表、压缩列表 } robj; 

5.2 Redis数据结构图

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

5.3 Redis扩容机制

因为我们的dictEntry数组默认大小是4,如果不进行扩容,那么我们所有的数据都会以链表的形式添加至数组下标 随着数据量越来越大,之前只需要hash取模就能得到下标位置,现在得去循环我下标的链表,所以性能会越来越慢,当我们的数据量达到一定程度后,我们就得去触发扩容操作。

5.3.1 什么时候扩容

5.3.1.1 扩容机制

  1. 当没有fork子进程在进行RDB或AOF持久化时,ht[0]的used大于size时,触发扩容
  2. 如果有子进程在进行RDB或者AOF时,ht[0]的used大于等于size的5倍的时候,会触发扩容

5.3.1.2 源码验证

扩容,肯定是在添加数据的时候才会扩容,所以我们找一个添加数据的入口。

  1. 入口,添加或替换dictReplace (dict.c文件)
 int dictReplace(dict *d, void *key, void *val) { dictEntry *entry, *existing, auxentry; /* Try to add the element. If the key * does not exists dictAdd will succeed. */ entry = dictAddRaw(d,key,&existing); if (entry) { dictSetVal(d, entry, val); return 1; } /* Set the new value and free the old one. Note that it is important * to do that in this order, as the value may just be exactly the same * as the previous one. In this context, think to reference counting, * you want to increment (set), and then decrement (free), and not the * reverse. */ auxentry = *existing; dictSetVal(d, existing, val); dictFreeVal(d, &auxentry); return 0; } 

2.进入dictAddRaw方法 (dict.c文件)

 dictEntry *dictAddRaw(dict *d, void *key, dictEntry existing){ long index; dictEntry *entry; dictht *ht; if (dictIsRehashing(d)) _dictRehashStep(d); //如果正在Rehash 进行渐进式hash 按步rehash /* Get the index of the new element, or -1 if * the element already exists. */ if ((index = _dictKeyIndex(d, key, dictHashKey(d,key),existing)) == -1) return NULL; /* Allocate the memory and store the new entry. * Insert the element in top, with the assumption that in a database * system it is more likely that recently added entries are accessed * more frequently. */ //如果在hash 放在ht[1] 否则放在ht[0] ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0]; entry = zmalloc(sizeof(*entry)); //采用头插法插入hash桶 entry->next = ht->table[index]; ht->table[index] = entry; //已使用++ ht->used++; /* Set the hash entry fields. */ dictSetKey(d, entry, key); return entry; } 

3.得到数据下标的方法 _dictKeyIndex (dict.c文件)

 static long _dictKeyIndex(dict *d, const void *key,uint64_t hash, dictEntry existing){ unsigned long idx, table; dictEntry *he; if (existing) *existing = NULL; /* Expand the hash table if needed */ //扩容如果需要 if (_dictExpandIfNeeded(d) == DICT_ERR) return -1; //比较是否存在这个值 for (table = 0; table <= 1; table++) { idx = hash & d->ht[table].sizemask; /* Search if this slot does not already contain the given key */ he = d->ht[table].table[idx]; while(he) { if (key==he->key || dictCompareKeys(d, key,he->key)) { if (existing) *existing = he; return -1; } he = he->next; } if (!dictIsRehashing(d)) break; } return idx; } 

4._dictExpandIfNeeded 验证是否需要扩容 (dict.c文件)

 /* Expand the hash table if needed */ static int _dictExpandIfNeeded(dict *d){ /* Incremental rehashing already in progress. Return.*/ if (dictIsRehashing(d)) return DICT_OK; //正在rehash,返回 /* If the hash table is empty expand it to the initialsize. */ //如果ht[0]的长度为0,设置默认长度4 dictExpand为扩容的关键方法 if (d->ht[0].size == 0) return dictExpand(d,DICT_HT_INITIAL_SIZE); //扩容条件 hash表中已使用的数量大于等于 hash表的大小 //并且dict_can_resize为1 或者 已使用的大小大于hash表大小的 5倍,大于等于1倍的时候,下面2个满足一个条件即可 if (d->ht[0].used >= d->ht[0].size && (dict_can_resize || d->ht[0].used/d->ht[0].size >dict_force_resize_ratio)){ //扩容成原来的2倍 return dictExpand(d, d->ht[0].used*2); } return DICT_OK; } 

 

5.3.2 怎么扩容

5.3.2.1 扩容步骤

  1. 当满足我扩容条件,触发扩容时,判断是否在扩容,如果在扩容,或者 扩容的大小跟我现在的ht[0].size一样,这次扩容不做
  2. new一个新的dictht,大小为ht[0].used * 2(但是必须向上2的幂,比 如6 ,那么大小为8) ,并且ht[1]=新创建的dictht
  3. 我们有个更大的table了,但是需要把数据迁移到ht[1].table ,所以将 dict的rehashidx(数据迁移的偏移量)赋值为0 ,代表可以进行数据迁 移了,也就是可以rehash了
  4. 等待数据迁移完成,数据不会马上迁移,而是采用渐进式rehash,慢慢的把数据迁移到ht[1]
  5. 当数据迁移完成,ht[0].table=ht[1] ,ht[1] .table = NULL、ht[1] .size = 0、ht[1] .sizemask = 0、 ht[1] .used = 0
  6. 把dict的rehashidex=-1

5.3.2.2 源码验证

  1. dictExpand方法在_dictExpandIfNeeded 方法中调用 (dict.c文件),为扩容的关键方法
 int dictExpand(dict *d, unsigned long size){ /* the size is invalid if it is smaller than the number of * elements already inside the hash table */ //正在扩容,不允许第二次扩容,或者ht[0]的数据量大于扩容后的数量,没有意义,这次不扩容 if (dictIsRehashing(d) || d->ht[0].used > size) return DICT_ERR; dictht n; /* the new hash table */ //得到最接近2的幂 跟hashMap思想一样 unsigned long realsize = _dictNextPower(size); /* Rehashing to the same table size is not useful. */ //如果跟ht[0]的大小一致 直接返回错误 if (realsize == d->ht[0].size) return DICT_ERR; /* Allocate the new hash table and initialize all pointers to NULL */ //为新的dictht赋值 n.size = realsize; n.sizemask = realsize-1; n.table = zcalloc(realsize*sizeof(dictEntry*)); n.used = 0; /* Is this the first initialization? If so it's not really a rehashing * we just set the first hash table so that it can accept keys. */ //ht[0].table为空,代表是初始化 if (d->ht[0].table == NULL) { d->ht[0] = n; return DICT_OK; } /* Prepare a second hash table for incremental rehashing */ //将扩容后的dictht赋值给ht[1] d->ht[1] = n; //标记为0,代表可以开始rehash d->rehashidx = 0; return DICT_OK; } 

 

5.3.3 数据怎么迁移(渐进式hash)

5.3.3.1 迁移方式

假如一次性把数据全部迁移会很耗时间,会让单条指令等待很久,会形成阻塞。

所以,redis采用渐进式Rehash,所谓渐进式,就是慢慢的,不会一次性把所有数据迁移。

 

那什么时候会进行渐进式数据迁移?

  1. 每次进行key的crud操作都会进行一个hash桶的数据迁移
  1. 定时任务,进行部分数据迁移

5.3.3.2 源码验证

CRUD触发都会触发_dictRehashStep(渐进式hash)

  1. 每次增删改的时候都会调用_dictRehashStep方法
 if (dictIsRehashing(d)) _dictRehashStep(d); //这个代码在增删改查的方法中都会调用 

2._dictRehashStep方法

 static void _dictRehashStep(dict *d) { if (d->iterators == 0) dictRehash(d,1); } 

3.dictRehash方法

 int dictRehash(dict *d, int n) { int empty_visits = n*10; /* Max number of empty buckets to visit. */ //要访问的最大的空桶数 防止此次耗时过长 if (!dictIsRehashing(d)) return 0; //如果没有在rehash返回0 //循环,最多1次,并且ht[0]的数据没有迁移完 进入循环 while(n-- && d->ht[0].used != 0) { dictEntry *de, *nextde; /* Note that rehashidx can't overflow as we are sure there are more * elements because ht[0].used != 0 */ assert(d->ht[0].size > (unsigned long)d->rehashidx); //rehashidx rehash的索引,默认0 如果hash桶为空 进入自旋 并且判断是否到了最大的访问空桶数 while(d->ht[0].table[d->rehashidx] == NULL) { d->rehashidx++; if (--empty_visits == 0) return 1; } de = d->ht[0].table[d->rehashidx]; //得到ht[0]的下标为rehashidx桶 /* Move all the keys in this bucket from the old to the new hash HT */ while(de) { //循环hash桶的链表 并且转移到ht[1] uint64_t h; nextde = de->next; /* Get the index in the new hash table */ h = dictHashKey(d, de->key) & d- >ht[1].sizemask; de->next = d->ht[1].table[h]; //头插 d->ht[1].table[h] = de; d->ht[0].used--; d->ht[1].used++; de = nextde; } //转移完后 将ht[0]相对的hash桶设置为null d->ht[0].table[d->rehashidx] = NULL; d->rehashidx++; } /* Check if we already rehashed the whole table... */ //ht[0].used=0 代表rehash全部完成 if (d->ht[0].used == 0) { //清空ht[0]table zfree(d->ht[0].table); //将ht[0] 重新指向已经完成rehash的ht[1] d->ht[0] = d->ht[1]; //将ht[1]所有数据重新设置 _dictReset(&d->ht[1]); //设置-1,代表rehash完成 d->rehashidx = -1; return 0; } /* More to rehash... */ return 1; } //将ht[1]的属性复位 static void _dictReset(dictht *ht) { ht->table = NULL; ht->size = 0; ht->sizemask = 0; ht->used = 0; } 

 

定时任务触发

再讲定时任务之前,我们要知道Redis中有个时间事件驱动,在 server.c文件下有个serverCron 方法。

serverCron 每隔多久会执行一次,执行频率根据redis.conf中的hz配置,serverCorn中有个方法databasesCron()

  1. 定时方法serverCron
 int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { //....... /* We need to do a few operations on clients asynchronously. */ clientsCron(); /* Handle background operations on Redis databases. */ databasesCron(); //处理Redis数据库上的后台操作。 //....... } 

2.databasesCron方法

 void databasesCron(void) { /* Expire keys by random sampling. Not required for slaves * as master will synthesize DELs for us. */ if (server.active_expire_enabled) { if (iAmMaster()) { activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW); } else { expireSlaveKeys(); } } /* Defrag keys gradually. */ activeDefragCycle(); /* Perform hash tables rehashing if needed, but only if there are no * other processes saving the DB on disk. Otherwise rehashing is bad * as will cause a lot of copy-on-write of memory pages. */ if (!hasActiveChildProcess()) { /* We use global counters so if we stop the computation at a given * DB we'll be able to start from the successive in the next * cron loop iteration. */ static unsigned int resize_db = 0; static unsigned int rehash_db = 0; int dbs_per_call = CRON_DBS_PER_CALL; int j; /* Don't test more DBs than we have. */ if (dbs_per_call > server.dbnum) dbs_per_call = server.dbnum; /* Resize */ for (j = 0; j < dbs_per_call; j++) { tryResizeHashTables(resize_db % server.dbnum); resize_db++; } /* Rehash */ //Rehash逻辑 if (server.activerehashing) { for (j = 0; j < dbs_per_call; j++) { //进入incrementallyRehash int work_done = incrementallyRehash(rehash_db); if (work_done) { /* If the function did some work, stop here, we'll do * more at the next cron loop. */ break; } else { /* If this db didn't need rehash, we'll try the next one. */ rehash_db++; rehash_db %= server.dbnum; } } } } } 

3.进入incrementallyRehash方法(server.c)

 int incrementallyRehash(int dbid) { /* Keys dictionary */ if (dictIsRehashing(server.db[dbid].dict)) { dictRehashMilliseconds(server.db[dbid].dict,1); return 1; /* already used our millisecond for this loop... */ } /* Expires */ if (dictIsRehashing(server.db[dbid].expires)) { dictRehashMilliseconds(server.db[dbid].expires,1); return 1; /* already used our millisecond for this loop... */ } return 0; } 

4.进入dictRehashMilliseconds(dict.c)

 int dictRehashMilliseconds(dict *d, int ms) { long long start = timeInMilliseconds(); int rehashes = 0; //进入rehash方法 dictRehash 去完成渐进时HASH while(dictRehash(d,100)) { rehashes += 100; //判断是否超时 if (timeInMilliseconds()-start > ms) break; } return rehashes; } 

 

5.4 String类型数据结构

Redis中String的底层没有用c的char来实现,而是采用了SDS(simple Dynamic String)的数据结构来实现。并且提供了5种不同的类型

5.4.1 SDS数据结构定义(sds.h文件)

 typedef char *sds; /* Note: sdshdr5 is never used, we just access the flags byte directly. * However is here to document the layout of type 5 SDS strings. */ struct __attribute__ ((__packed__)) sdshdr5 { unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ char buf[]; } struct __attribute__ ((__packed__)) sdshdr8 { uint8_t len; /* used */ //已使用的长度 uint8_t alloc; /* excluding the header and null terminator */ //分配的总容量 不包含头和空终止符 unsigned char flags; /* 3 lsb of type, 5 unused bits */ //低三位类型 高5bit未使用 char buf[]; //数据buf 存储字符串数组 }; struct __attribute__ ((__packed__)) sdshdr16 { uint16_t len; /* used */ uint16_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ char buf[]; }; struct __attribute__ ((__packed__)) sdshdr32 { uint32_t len; /* used */ uint32_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ char buf[]; }; struct __attribute__ ((__packed__)) sdshdr64 { uint64_t len; /* used */ uint64_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ char buf[]; }; 

5.4.2 SDS数据结构的优势

  1. char字符串不记录自身长度,所以获取一个字符串长度的复杂度是O(n),但是SDS记录分配的长度alloc,已使用的长度len,获取长度为 O(1)
  2. 减少修改字符串带来的内存重分配次数
  • 空间预分配,SDS长度如果小于1MB,预分配跟长度一样的,大于1M,每次跟len的大小多1M
  • 惰性空间释放,截取的时候不马上释放空间,供下次使用!同时提供相应的释放SDS未使用空间的API

3. 二进制安全

5.5 Hash类型数据结构

Redis的字典相当于Java语言中的HashMap,他是无序字典。内部结构上同样是数组 + 链表二维结构。第一维hash的数组位置碰撞时,就会将碰撞的素使用链表串起来。

5.5.1 Hash数据结构图

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

5.5.2 Hash的压缩列表

压缩列表会根据存入的数据的不同类型以及不同大小,分配不同大小的空间。所以是为了节省内存而采用的。

因为是一块完整的内存空间,当里面的素发生变更时,会产生连锁更新,严重影响我们的访问性能。所以,只适用于数据量比较小的场景。

所以,Redis会有相关配置,Hashes只有小数据量的时候才会用到ziplist,当hash对象同时满足以下两个条件的时候,使用ziplist编码:

  1. 哈希对象保存的键值对数量<512个
  2. 所有的键值对的键和值的字符串长度都<64byte(一个英文字母一个字节)
 hash-max-ziplist-value 64 // ziplist中最大能存放的值长度 hash-max-ziplist-entries 512 // ziplist中最多能存放的entry节点数量 

5.6 List类型数据结构

5.6.1 quickList快速列表

兼顾了ziplist的节省内存,并且一定程度上解决了连锁更新的问题,我们的 quicklistNode节点里面是个ziplist,每个节点是分开的。那么就算发生了连锁更新,也只会发生在一个quicklistNode节点。

quicklist.h文件

 typedef struct{ struct quicklistNode *prev; //前指针 struct quicklistNode *next; //后指针 unsigned char *zl; //数据指针 指向ziplist结果 unsigned int sz; //ziplist大小 /* ziplist size in bytes */ unsigned int count : 16; /* count of items in ziplist */ //ziplist的素 unsigned int encoding : 2; /* RAW==1 or LZF==2 */ // 是否压缩, 1没有压缩 2 lzf压缩 unsigned int container : 2; /* NONE==1 or ZIPLIST==2 */ //预留容器字段 unsigned int recompress : 1; /* was this node previous compressed? */ unsigned int attempted_compress : 1; /* node can't compress; too small */ unsigned int extra : 10; /* more bits to steal for future usage */ //预留字段 } quicklistNode; 

 

5.6.2 list数据结构图

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

5.7 Set类型数据结构

Redis用intset或hashtable存储set。满足下面条件,就用inset存储。

  1. 如果不是整数类型,就用dictht hash表(数组+链表)
  2. 如果素个数超过512个,也会用hashtable存储。跟一个配置有关:
 set-max-intset-entries 512 

不满足上述条件的,都使用hash表存储,value存null。

5.8 ZSet数据结构

5.8.1 ZipList

默认使用ziplist编码。

在ziplist的内部,按照score排序递增来存储。插入的时候要移动之后的数据。

如果素数量大于等于128个,或者任一member长度大于等于64字节使用 skiplist+dict存储。

 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 

如果不满足条件,采用跳表。

5.8.2 跳表(skiplist)

结构定义(servier.h)

 /* ZSETs use a specialized version of Skiplists */ typedef struct zskiplistNode { sds ele; //sds数据 double score; //score struct zskiplistNode *backward; //后退指针 //层级数组 struct zskiplistLevel { struct zskiplistNode *forward; //前进指针 unsigned long span; //跨度 } level[]; } zskiplistNode; //跳表列表 typedef struct zskiplist { struct zskiplistNode *header, *tail; //头尾节点 unsigned long length; //节点数量 int level; //最大的节点层级 } zskiplist; 

zslInsert 添加节点方法 (t_zset.c)

 zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) { zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x; unsigned int rank[ZSKIPLIST_MAXLEVEL]; int i, level; serverAssert(!isnan(score)); x = zsl->header; for (i = zsl->level-1; i >= 0; i--) { /* store rank that is crossed to reach the insert position */ rank[i] = i == (zsl->level-1) ? 0 : rank[i+1]; while (x->level[i].forward && (x->level[i].forward->score < score || 咕泡出品 必属精品精品属精品 咕泡出品 必属精品 咕泡出品 必属精品 咕泡咕泡 (x->level[i].forward->score == score && sdscmp(x->level[i].forward->ele,ele) < 0))) { rank[i] += x->level[i].span; x = x->level[i].forward; } update[i] = x; } /* we assume the element is not already inside, since we allow duplicated * scores, reinserting the same element should never happen since the * caller of zslInsert() should test in the hash table if the element is * already inside or not. */ level = zslRandomLevel(); if (level > zsl->level) { for (i = zsl->level; i < level; i++) { rank[i] = 0; update[i] = zsl->header; update[i]->level[i].span = zsl->length; } zsl->level = level; } x = zslCreateNode(level,score,ele); //不同层级建立链表联系 for (i = 0; i < level; i++) { x->level[i].forward = update[i]->level[i].forward; update[i]->level[i].forward = x; /* update span covered by update[i] as x is inserted here */ x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]); update[i]->level[i].span = (rank[0] - rank[i]) + 1; } /* increment span for untouched levels */ for (i = level; i < zsl->level; i++) { update[i]->level[i].span++; } x->backward = (update[0] == zsl->header) ? NULL : update[0]; if (x->level[0].forward) x->level[0].forward->backward = x; else zsl->tail = x; zsl->length++; return x; } 

ZSKIPLIST_MAXLEVEL默认32 定义在server.h

 #define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^64 elements */ 

六、Redis过期策略

6.1 惰性过期

所谓惰性过期,就是在每次访问操作key的时候,判断这个key是不是过期了,过期了就删除。

6.1.1 源码验证

  1. expireIfNeeded方法(db.c文件)
 int expireIfNeeded(redisDb *db, robj *key) { if (!keyIsExpired(db,key)) return 0; /* If we are running in the context of a slave, instead of * evicting the expired key from the database, we return ASAP: * the slave key expiration is controlled by the master that will * send us synthesized DEL operations for expired keys. * * Still we try to return the right information to the caller, * that is, 0 if we think the key should be still valid, 1 if * we think the key is expired at this time. */ // 如果配置有masterhost,说明是从节点,那么不操作删除 if (server.masterhost != NULL) return 1; /* Delete the key */ server.stat_expiredkeys++; propagateExpire(db,key,server.lazyfree_lazy_expire); notifyKeyspaceEvent(NOTIFY_EXPIRED, "expired",key,db->id); //是否是异步删除 防止单个Key的数据量很大 阻塞主线程 是4.0之后添加的新功能,默认关闭 int retval = server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) : dbSyncDelete(db,key); if (retval) signalModifiedKey(NULL,db,key); return retval; } 

每次调用到相关指令时,才会执行expireIfNeeded判断是否过期,平时不会去判断是否过期。

该策略可以最大化的节省CPU资源。

但是却对内存非常不友好。因为如果没有再次访问,就可能一直堆积再内存中。占用内存

所以就需要另一种策略来配合使用,就是定期过期

6.2 定期过期

那么多久去清除一次,我们在讲Rehash的时候,有个方法是serverCron,执行频率根据redis.conf中的hz配置。

这方法除了做Rehash以外,还会做很多其他的事情,比如:

  1. 清理数据库中的过期键值对
  2. 更新服务器的各类统计信息,比如时间、内存占用、数据库占用情况等
  3. 关闭和清理连接失效的客户端
  4. 尝试进行持久化操作

6.2.1 实现流程

  1. 定时serverCron方法去执行清理,执行频率根据redis.cong中的hz配置的值(默认是10,也就是1s执行10次,100ms执行一次)
  2. 执行清理的时候,不是去扫描所有的key,而是去扫描所有设置了过期时间的key redisDB.expires
  3. 如果每次去把所有的key都拿出来,那么假如过期的key很多,就会很慢,所以也不是一次性拿出所有的key
  4. 根据hash桶的维度去扫描key,扫到20(可配置)个key为止。假如第一个桶是15个key没有满足20,继续扫描第二个桶,第二个桶20个key,由于是以hash桶的维度扫描的,所以第二个扫到了就会全扫,总共扫描35个key
  5. 找到扫描的key里面过期的key,并进行删除
  6. 如果取了400个空桶(最多拿400个桶),或者扫描的删除比例跟扫描的总数超过10%,继续执行4、5步
  7. 也不能无限的循环,循环16次后回去检测时间,超过指定时间会跳出

6.2.2 源码验证

  1. 入口serverCrom
 // serverCron方法调用databasesCron方法(server.c) /* Handle background operations on Redis databases. */ databasesCron(); void databasesCron(void) { /* Expire keys by random sampling. Not required for slaves * as master will synthesize DELs for us. */ if (server.active_expire_enabled) { if (iAmMaster()) { activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW); //过期删除方法 } else { expireSlaveKeys(); } } } 

七、Redis淘汰策略

由于Redis内存是有大小的,并且我可能里面的数据都没有过期,当快满的时候,我又没有过期的数据进行淘汰,那么这个时候内存也会满。内存满了,Redis也会不能放入新的数据。所以,我们不得已需要一些策略来解决这个问题来保证可用性。

7.1 淘汰策略

7.1.1 noeviction

New values aren’t saved when memory limit is reached. When a database uses replication, this applies to the primary database.

默认,不淘汰 能读不能写

7.1.2 allkeys-lru

Keeps most recently used keys; removes least recently used (LRU) keys

基于伪LRU算法,在所有的key中去淘汰

7.1.3 allkeys-lfu

Keeps frequently used keys; removes least frequently used (LFU) keys.

基于伪LFU算法,在所有的key中去淘汰

7.1.4 volatile-lru

Removes least recently used keys with the expire field set to true.

基于伪LRU算法,在设置了过期时间的key中去淘汰

7.1.5 volatile-lfu

Removes least frequently used keys with the expire field set to true.

基于伪LFU算法 在设置了过期时间的key中去淘汰

7.1.6 allkeys-random

Randomly removes keys to make space for the new data added.

基于随机算法,在所有的key中去淘汰

7.1.7 volatile-random

Randomly removes keys with expire field set to true.

基于随机算法 在设置了过期时间的key中去淘汰

7.1.8 volatile-ttl

Removes least frequently used keys with expire field set to true and the shortest remaining time-to-live (TTL) value.

根据过期时间来,淘汰即将过期的

7.2 淘汰流程

  1. 首先,我们会有个淘汰池,默认大小是16,并且里面的数据是末尾淘汰制
  2. 每次指令操作的时候,自旋会判断当前内存是否满足指令所需要的内存
  3. 如果当前不满足,会从淘汰池的尾部拿一个最适合淘汰的数据
  • 会取样(配置 maxmemory-samples),从Redis中获取随机获取到取样的数据,解决一次性读取所有的数据慢的问题
  • 在取样的数据中,根据淘汰算法找到最适合淘汰的数据
  • 将最合适的那个数据跟淘汰池中的数据进行比较,是否比淘汰池的数据更适合淘汰,如果更适合,放入淘汰池
  • 按照适合的程度进行排序,最适合淘汰的放入尾部

4.将需要淘汰的数据从Redis删除,并且从淘汰池移除

7.3 LRU算法

Lru,Least Recently Used 翻译过来是最久未使用,根据时间轴来走,仍很久没用的数据。只要最近有用过,我就默认是有效的。

那么它的一个衡量标准是啥?时间!根据使用时间,从近到远,越远的越容易淘汰。

7.3.1 实现原理

需求:得到对象隔多久没访问,隔的时间越久,越容易被淘汰

  1. 首先,LRU是根据这个对象的访问操作时间来进行淘汰的,那么我们需要知道这个对象最后操作的访问时间
  2. 知道了对象的最后操作访问时间后,我们只需要跟当前系统时间来进行对比,就能算出对象多久没访问了

7.3.2 源码验证

redis中,对象都会被redisObject对象包装,其中有个字段叫lru。

redisObject对象 (server.h文件)

 typedef struct redisObject { unsigned type:4; unsigned encoding:4; unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency * and most significant 16 bits access time). */ int refcount; void *ptr; } robj; 

看LRU的字段的说明,那么我们大概能猜出来,redis去实现lru淘汰算法肯定跟我们这个对象的lru相关

并且这个字段的大小为24bit,那么这个字段记录的是对象操作访问时候的秒单位时间的后24bit

相当于:

 long timeMillis=System.currentTimeMillis(); System.out.println(timeMillis/1000); //获取当前秒 System.out.println(timeMillis/1000 & ((1<<24)-1)); //获取秒的后24位 

我们知道了这个对象的最后操作访问的时间。如果我们要得到这个对象多久没访问了,我们是不是就很简单,用我当前的时间-这个对象的访问时间就可以了!但是这个访问时间是秒单位时间的后24bit 所以,也是用当前的时间的秒单位的后24bit去减。

estimateObjectIdleTime方法(evict.c)

 unsigned long long estimateObjectIdleTime(robj *o) { //获取秒单位时间的最后24位 unsigned long long lruclock = LRU_CLOCK(); //因为只有24位,所有最大的值为2的24次方-1 //超过最大值从0开始,所以需要判断lruclock(当前系统时间)跟缓存对象的lru字段的大小 if (lruclock >= o->lru) { //如果lruclock>=robj.lru,返回lruclock-o->lru,再转换单位 return (lruclock - o->lru) * LRU_CLOCK_RESOLUTION; } else { //否则采用lruclock + (LRU_CLOCK_MAX - o->lru),得到对 象的值越小,返回的值越大,越大越容易被淘汰 return (lruclock + (LRU_CLOCK_MAX - o->lru)) * LRU_CLOCK_RESOLUTION; } } 

 

7.3.3 LRU总结

用lruclock与 redisObject.lru进行比较,因为lruclock只获取了当前秒单位时间的后24位,所以肯定有个轮询。

所以,我们会用lruclock跟 redisObject.lru进行比较,如果lruclock>redisObject.lru,那么我们用lruclock- redisObject.lru,否则lruclock+(24bit的最大值-redisObject.lru),得到lru越小,那么返回的数据越大,相差越大的越优先会被淘汰!

https://www.processon.com/view/link/5fbe0541e401fd2d6ed8fc38

7.4 LFU算法

LFU,英文 Least Frequently Used,翻译成中文就是最不常用的优先淘汰。

不常用,它的衡量标准就是次数,次数越少的越容易被淘汰。

这个实现起来应该也很简单,对象被操作访问的时候,去记录次数,每次操作访问一次,就+1;淘汰的时候,直接去比较这个次数,次数越少的越容易淘汰!

7.4.1 LFU的时效性问题

何为时效性问题?就是只会去考虑数量,但是不会去考虑时间。

ps:去年的某个新闻很火,量3000W,今年有个新闻刚出来量100次,本来我们是想保留今年的新的新闻的,但是如果根据LFU来做的话,我们发现淘汰的是今年的新闻,明显是不合理的

导致的问题:新的数据进不去,旧的数据出不来。

那么如何解决呢,且往下看

7.4.2 源码分析

我们还是来看redisObject(server.h)

 typedef struct redisObject { unsigned type:4; unsigned encoding:4; unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency * and most significant 16 bits access time). */ int refcount; void *ptr; } robj; 

我们看它的lru,它如果在LFU算法的时候!它前面16位代表的是时间,后8位代表的是一个数值,frequency是频率,应该就是代表这个对象的访问次数,我们先给它叫做counter。

前16bits时间有啥用?

跟时间相关,我猜想应该是跟解决时效性相关的,那么怎么解决的?从生活中找例子

大家应该充过一些会员,比如我这个年纪的,小时候喜欢充腾讯的黄钻、绿钻、蓝钻等等。但是有一个点,假如哪天我没充钱了的话,或者没有续VIP的时候,我这个钻石等级会随着时间的流失而降低。比如我本来是黄钻V6,但是一年不充钱的话,可能就变成了V4。

那么回到Redis,大胆的去猜测,那么这个时间是不是去记录这个对象有多久没访问了,如果多久没访问,我就去减少对应的次数。

LFUDecrAndReturn方法(evict.c)

 unsigned long LFUDecrAndReturn(robj *o) { //lru字段右移8位,得到前面16位的时间 unsigned long ldt = o->lru >> 8; //lru字段与255进行&运算(255代表8位的最大值), //得到8位counter值 unsigned long counter = o->lru & 255; //如果配置了lfu_decay_time,用LFUTimeElapsed(ldt) 除以配置的值 //LFUTimeElapsed(ldt)源码见下 //总的没访问的分钟时间/配置值,得到每分钟没访问衰减多少 unsigned long num_periods = server.lfu_decay_time ?LFUTimeElapsed(ldt) / server.lfu_decay_time : 0; if (num_periods) //不能减少为负数,非负数用couter值减去衰减值 counter = (num_periods > counter) ? 0 : counter - num_periods; return counter; } 

衰减因子由配置

 lfu-decay-time 1 //多少分钟没操作访问就去衰减一次 

后8bits的次数,最大值是255,够不够?

肯定不够,一个对象的访问操作次数肯定不止255次。

但是我们可以让数据达到255的很难。那么怎么做的?这个比较简单,我们先看源码,然后再总结

LFULogIncr方法 (evict.c 文件)

 uint8_t LFULogIncr(uint8_t counter) { //如果已经到最大值255,返回255 ,8位的最大值 if (counter == 255) return 255; //得到随机数(0-1) double r = (double)rand()/RAND_MAX; //LFU_INIT_VAL表示基数值(在server.h配置) double baseval = counter - LFU_INIT_VAL; //如果达不到基数值,表示快不行了,baseval =0 if (baseval < 0) baseval = 0; //如果快不行了,肯定给他加counter //不然,按照几率是否加counter,同时跟baseval与lfu_log_factor相关 //都是在分子,所以2个值越大,加counter几率越小 double p = 1.0/(baseval*server.lfu_log_factor+1); if (r < p) counter++; return counter; } 

 

八、Redis 持久化

8.1 RBD

8.1.1 何时触发RBD

自动触发

  1. 配置触发
 save 900 1 900s检查一次,至少有1个key被修改就触发 save 300 10 300s检查一次,至少有10个key被修改就触发 save 60 10000 60s检查一次,至少有10000个key被修改 

2. shutdown正常关闭

任何组件在正常关闭的时候,都会去完成应该完成的事。比如Mysql 中的Redolog持久化,正常关闭的时候也会去持久化。

3. flushall指令触发

数据清空指令会触发RDB操作,并且是触发一个空的RDB文件,所以, 如果在没有开启其他的持久化的时候,flushall是可以删库跑路的,在生产环境慎用。

8.1.2 RDB的优劣

优势

  1. 是个非常紧凑型的文件,非常适合备份与灾难恢复
  2. 最大限度的提升了性能,会fork一个子进程,父进程永远不会产于磁盘 IO或者类似操作
  3. 更快的重启

不足

  1. 数据安全性不是很高,因为是根据配置的时间来备份,假如每5分钟备份 一次,也会有5分钟数据的丢失
  2. 经常fork子进程,所以比较耗CPU,对CPU不是很友好

8.2 AOF

由于RDB的数据可靠性非常低,所以Redis又提供了另外一种持久化方案: Append Only File 简称:AOF

AOF默认是关闭的,你可以在配置文件中进行开启:

 appendonly no //默认关闭,可以进行开启 # The name of the append only file (default:"appendonly.aof") appendfilename "appendonly.aof" //AOF文件名 

追加文件,即每次更改的命令都会附加到我的AOF文件中。

8.2.1 同步机制

AOF会记录每个写操作,那么问题来了。我难道每次操作命令都要和磁盘交互?

当然不行,所以redis支持几种策略,由用户来决定要不要每次都和磁盘交互

 # appendfsync always 表示每次写入都执行fsync(刷新)函数 性能会非常非常慢 但是非常安全 appendfsync everysec 每秒执行一次fsync函数 可能丢失1s的数据 # appendfsync no 由操作系统保证数据同步到磁盘,速度最快 你的数据只需要交给操作系统就行 

默认1s一次,最多有1s丢失

8.2.2 重写机制

由于AOF是追加的形式,所以文件会越来越大,越大的话,数据加载越慢。 所以我们需要对AOF文件进行重写。

何为重写

比如 我们的incr指令,假如我们incr了100次,现在数据是100,但是我们的aof文件中会有100条incr指令,但是我们发现这个100条指令用处不大, 假如我们能把最新的内存里的数据保存下来的话。所以,重写就是做了这么一件事情,把当前内存的数据重写下来,然后把之前的追加的文件删除。

重写流程

  • 在Redis7之前
  1. Redis fork一个子进程,在一个临时文件中写入新的AOF(当前内存的数据生成的新的AOF)
  2. 那么在写入新的AOF的时候,主进程还会有指令进入,那么主进程会在内存缓存区中累计新的指令 (但是同时也会写在旧的AOF文件中,就算 重写失败,也不会导致AOF损坏或者数据丢失)
  3. 如果子进程重写完成,父进程会收到完成信号,并且把内存缓存中的指令追加到新的AOF文件中
  4. 替换旧的AOF文件 ,并且将新的指令附加到重写好的AOF文件中

 

  • 在Redis7之后,AOF文件不再是一个,所以会有临时清单的概念
  1. 子进程开始在一个临时文件中写入新的基础AOF
  2. 父级打开一个新的增量 AOF 文件以继续写入更新。如果重写失败,旧的基础和增量文件(如果有的话)加上这个新打开的增量文件就代表了完整的更新数据集,所以我们是安全的
  3. 当子进程完成基础文件的重写后,父进程收到一个信号,并使用新打开 的增量文件和子进程生成的基础文件来构建临时清单,并将其持久化
  4. 现在 Redis 对清单文件进行原子交换,以便此 AOF 重写的结果生效。 Redis 还会清理旧的基础文件和任何未使用的增量文件

 

但是重写是把当前内存的数据,写入一个新的AOF文件,如果当前数据比较大,然后以指令的形式写入的话,会很慢很慢

所以在4.0之后,在重写的时候是采用RDB的方式去生成新的AOF文件,然 后后续追加的指令,还是以指令追加的形式追加的文件末尾

 aof-use-rdb-preamble yes //是否开启RDB与AOF混合模式 

 

什么时候重写

配置文件redis.conf

 # 重写触发机制 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb 就算达到了第一个百分比的大小,也必须大于 64M 在 aof 文件小于64mb的时候不进行重写,当到达64mb的时候,就重写一 次。重写后的 aof 文件可能是40mb。上面配置了auto-aof-rewritepercentag为100,即 aof 文件到了80mb的时候,进行重写。 

8.2.3 AOF的优势与不足

优势

  1. 安全性高,就算是默认的持久化同步机制,也最多只会丢失1s数据
  2. AOF由于某些原因,比如磁盘满了等导致追加失败,也能通过redischeck-aof 工具来修复
  3. 格式都是追加的日志,所以可读性更高

不足

  1. 数据集一般比RDB大
  2. 持久化跟数据加载比RDB更慢
  3. 在7.0之前,重写的时候,因为重写的时候,新的指令会缓存在内存区,所以会导致大量的内存使用
  4. 并且重写期间,会跟磁盘进行2次IO,一个是写入老的AOF文件,一个是写入新的AOF文件

九、Redis常见问题总结

9.1 Redis数据丢失场景

9.1.1 持久化丢失

采用RDB或者不持久化, 会有数据丢失,因为是手动或者配置以快照的形式来进行备份。

解决:启用AOF,以命令追加的形式进行备份,但是默认也会有1s丢失, 这是在性能与数据安全性中寻求的一个最适合的方案,如果为了保证数据 一致性,可以将配置更改为always,但是性能很慢,一般不用。

 

9.1.2 主从切换

因为Redis的数据是主异步同步给从的,提升了性能,但是由于是异步同步到从。所以存在数据丢失的可能

  1. master写入数据k1 ,由于是异步同步到slave,当master没有同步给slave的时候,master挂了
  2. slave会成为新的master,并且没有同步k1
  3. master重启,会成为新master的slave,同步数据会清空自己的数据,从新的master加载
  4. k1丢失

9.2 Redis缓存雪崩、穿透、击穿问题分析

9.2.1 缓存雪崩

缓存雪崩就是Redis的大量热点数据同时过期(失效),因为设置了相同的过期时间,刚好这个时候Redis请求的并发量又很大,就会导致所有的请求落到数据库。

  1. 保证Redis的高可用,防止由于Redis不可用导致全部打到DB
  2. 加互斥锁或者使用队列,针对同一个key只允许一个线程到数据库查询
  3. 缓存定时预先更新,避免同时失效
  4. 通过加随机数,使key在不同的时间过期

9.2.2 缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,但是用户一直请求不存在的数据!这时的用户很可能就是攻击者,恶意搞你们公司的,攻击会导致数据库压力过大。

解决方案:布隆过滤器

布隆过滤器的思想:既然是因为你Redis跟DB都没有,然后用户恶意一直访问不存在的key,然后全部打到Redis跟DB。那么我们能不能单独把DB的数据单独存到另外一个地方,但是这个地方只存一个简单的标记,标记这个key存不存在,如果存在,就去访问Redis跟DB,否则直接返回。并且这个内存最好很小。

9.2.3 缓存击穿

单个key过期的时候有大量并发,使用互斥锁,回写redis,并且采用双重检查锁来提升性能!减少对DB的访问。

作者:京东科技 张石磊

1 案例引入

名词简介:

资源:可以理解为一条内容,或者图+文字+链接的载体。

档位ID: 资源的分类组,资源必须归属于档位。

问题描述:当同一个档位下2条资源同时审批通过时,收到擎天审批系统2条消息,消费者应用部署了2台机器,此时正好由2台机器分别消费,在并发消费时,先更新资源状态,然后写缓存,每次取前100条资源,类似select * from resource where gear_id=xxx limit 100 order by id desc;

在写档位缓存,此时事务未提交,并发查询时根据档位Id查询时查询不到对方的数据,全量写缓存时导致后写的缓存覆盖了先写的缓存,即缓存被覆盖,导致投放资源缺失。

方案思考 :

方案1:一台机器消费mq–单点问题

方案2:将同档位ID的资源路由到同一个queue,需要审批系统配合根据档位Id做路由,审批系统发的消息不只是cms审批数据,此方案不适用。

方案3:在档位级别加分布式锁。

经比较,最终采用方案3是合适的方案.

2 锁说明和分布式锁选择

synchronized锁的粒度是JVM进程维度,集群模式下,不能对共享资源加锁,此时需要跨JVM进程的分布式锁。

分布式锁方式核心实现方式优点缺点分析

1 数据库:

悲观锁,lock

乐观锁,通过版本号实现version

实现简单,不依赖中间件

数据库IO瓶颈,性能差

单实例存在单点问题,主从架构存在数据不一致,主从切换时其他客户端可重复加锁。

2 zookeeper

创建临时节点

CP模型,可靠性高,不存在主从切换不一致问题

频繁创建和销毁临时节点,且

集群模式下,leader数据需要同步到follower才算加锁成功,性能不如redis

主从切换服务不可用

3 redis集群

setnx+expire

性能高

有封装好的框架redission

支持超时自动删除锁

集群支持高可用,AP模型

主从切换时其他客户端可重复加锁。

R2M是基于开源的Redis cluster(Redis 3.0以上版本)构建的高性能分布式缓存系统,我们系统一直在使用,3.2.5版本开始支持分布式锁。

3 r2m分布式锁原理

示例代码:

 

1 加锁核心流程:

加锁流程图:

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

1):尝试获取锁,通过执行加锁Lua脚本来做;

2):若第一步未获取到锁,则去redis订阅解锁消息

3):一旦持有锁的线程释放了锁,就会广播解锁消息,其他线程自旋重新尝试获取锁。

核心加锁原理:使用lua脚本封装了hset和pexpire命令,保证是一个原子操作, KEYS[1]是加锁的key,argv[2]是加锁的客户端ID(UUID+线程ID),ARGV[1]是锁的有效期,默认30s.

 

args参数

 

获取锁失败订阅锁的channel

 

锁释放后,订阅者通过自旋尝试获取锁。

 

2 释放锁核心逻辑:

1)删除分布式锁key(如果可重入锁计数为0)

  1. 发释放锁的广播消息

3)取消watchdog

 

3 锁的健壮性思考

1 业务没执行完,锁超时过期怎么办?

客户端加锁默认有效期30s,超过有效期后如果业务没执行完,还需要持有这把锁,r2m客户端提供了续期机制,也就是watchdog机制。

watchdog原理:客户端线程维度(UUID+线程ID,客户端维护一个MAP,key就是UUID+线程ID)的后台定时线程,获取锁成功后,如果客户端还持有当前锁,每隔10s(this.internalLockLeaseTime() / 3L),去延长锁的有效期(internalLockLeaseTime)

 

2 客户端宕机,锁如何释放?

分布式锁是有效期的,客户端宕机后,watchdog机制失效,锁过期自动失效。

3 redis分布式锁集群模式下缺陷

r2m集群模式,极端情况,master加锁成功,宕机,还未来得及同步到slave,主从切换,slave切换成master,可以继续加锁,对于非及其严格加锁场景,该方案可满足,属于AP;对于严格场景下的分布式锁,可采用基于zookeeper的分布式锁,属于CP,leader宕机,folllower选举时不可用。性能上redis更优。

4 锁的释放问题

注意锁的释放在finally中释放,必须由锁的持有者释放,不能由其他线程释放别人的锁,示例代码中lock放到try的外面。

积木 v2.3.1 已经发布,Java 后台管理系统

此版本更新内容包括:

1、支持免tomcat运行

2、支持打包docker

3、集成satoken,同时支持多管理平台集成

4、配置信息全db提取(除了db连接,配置表:bb_sys_params)

5、本环境为安装环境,启动后续配置db连接

运行

1、基于setup环境打包

2、bb-project-release 路径下,jfinal.bat start 或者 jfinal.sh start 推荐先自行建库

详情查看:https://gitee.com/RemoteControl/BB/releases/v2.3.1

v1.0.0 更新内容:
1、设计、规划和研发基础 RBAC 权限架构;
2、编写框架核心底层代码,设计基于 Layout 布局的模板,设计并编写自定义模板 html 文件;
3、对系统模板进行架构设计及模板继承相关设计;
4、研发框架基础模块,如字典、配置、行政区划管理等等常规基础模块;
5、设计并研发代码生成器,根据表结构动态解析并生成模块文件和增删改查功能;
6、设计并研发一系列其他配套功能很常规使用函数;
7、设计并研发框架核心组件 widget;

项目介绍

一款 Python 语言基于Django、Layui、MySQL等框架精心打造的一款模块化、高性能、企业级的敏捷开发框架,本着简化开发、提升开发效率的初衷触发,框架自研了一套个性化的组件,实现了可插拔的组件式开发方式:单图上传、多图上传、下拉选择、开关按钮、单选按钮、多选按钮、图片裁剪等等一系列个性化、轻量级的组件,是一款真正意义上实现组件化开发的敏捷开发框架。

内置模块

  • 用户管理:用于维护管理系统的用户,常规信息的维护与账号设置。
  • 角色管理:角色菜单管理与权限分配、设置角色所拥有的菜单权限。
  • 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
  • 职级管理:主要管理用户的职级。
  • 岗位管理:主要管理用户担任职务。
  • 部门管理:配置系统组织机构,树结构展现支持数据权限。
  • 字典管理:对系统中常用的较为固定的数据进行统一维护。
  • 配置管理:对系统的常规配置信息进行维护,网站配置管理功能进行统一维护。

 软件信息

  • 软件名称:DjangoAdmin敏捷开发框架Django+Layui版本
  • 官网网址:https://www.djangoadmin.cn
  • 文档网址:http://docs.django.layui.djangoadmin.cn

系统演示

  • 演示地址:http://manage.django.layui.djangoadmin.cn
账号 密码 操作权限 admin 演示环境无法进行修改删除操作

核心组件

  • 单图上传组件
 {% image "avatar|头像|90x90|建议上传尺寸450x450|450x450" data.avatar "" 0 %} 

  • 多图上传组件
 {% album "avatar|图集|90x90|20|建议上传尺寸450x450" "" "png,jpg" 10 %} 

  • 下拉选择组件
 {% select "gender|1|性别|name|id" "1=男,2=女,3=保密" data.gender %} 

  • 单选按钮组件
 {% radio "gender|name|id" "1=男,2=女,3=保密" 1 %} 

  • 复选框组件
 {% checkbox "gender|name|id" "1=男,2=女,3=保密" 1 %} 

  • 城市选择组件
 {% city data.district_code 3 1 %} 

  • 开关组件
 {% switch "status" "是|否" data.status|default:1 %} 

  • 日期组件
 {% date "birthday|1|出生日期|date" data.birthday %} 

  • 图标组件
 {{ "icon"|icon:data.icon }} 

  • 穿梭组件
 {% transfer "func|0|全部节点,已赋予节点|name|id|220x350" "1=列表,5=添加,10=修改,15=删除,20=详情,25=状态,30=批量删除,35=添加子级,40=全部展开,45=全部折叠,50=导出数据,55=导入数据,60=分配权限,65=重置密码" funcList %} 

模块展示

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

特别鸣谢

感谢Django、Layui等优秀开源项目。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

回顾

腾讯 APIJSON 是一种专为 API 而生的 JSON 网络传输协议 以及 基于这套协议实现的 ORM 库。
为各种增删改查提供了完全自动化的万能 API,零代码实时满足千变万化的各种新增和变更需求。
能大幅降低开发和沟通成本,简化开发流程,缩短开发周期。适合中小型前后端分离的项目。

自 2016 年 11 月开源 6 年来发展迅速,目前 14K+ Star 位居 400W Java 开源项目前 100。

image

image

国内 腾讯、华为、阿里巴巴、美团、字节跳动、百度、京东、网易、快手、圆通 等 和
国外 Google, Microsoft, Amazon, Paypal, IBM, Shopee 等数百名知名大厂员工点了 Star,
也有 腾讯、华为、字节跳动、Microsoft、Zoom、知乎 等 工程师/专家/架构师 提了 PR/Issue,
还被 腾讯、华为、百度、SHEIN、快手、中兴、传音、圆通、美图 等各大知名厂商用于各类项目。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

APIJSON 6.0.0 更新

功能

新增支持全能接口 /crud,一个请求 JSON 同时使用多种 CRUD 操作,并支持跨源事务,感谢 @cloudAndMonkey 的贡献 #481 #485;
新增支持 Elasticsearch(简称 ES), Kafka(MQ 消息队列),感谢 @cloudAndMonkey 的贡献 #487 #493;
新增支持 JS, Lua 等各种脚本语言,感谢 @cloudAndMonkey 的贡献 #500;

新增校验请求字符串长度的规则,感谢 @aninZz 的贡献 #498;
简化依赖,感谢阿里云工程师 @cnscoo 的贡献 #489;

文档

新增包括阿里云工程师在内的 8 个贡献者,特别致谢 @cloudAndMonkey 贡献全能 CRUD、Elasticsearch, WITH AS、跨库跨源事务 等
新增文章《apijson 初探》,感谢 x3d 的贡献,点赞/收藏/关注 作者来支持下 TA 吧~
增加《APIJSON使用文档》链接,感谢 @12345ZMTHL 的贡献 #483,点赞、收藏支持下热心的作者吧~
Fix typo in Document-English.md,thanks to @eltociear ‘s contribution #472;

 

完整更新日志具体见 Release 发布版本。

 

APIJSON 九阴真经 – 软件开发行业的 ATM 机

接口全万能,前端不求人。要啥就有啥,所求即所得。
需求由它变,后端稳如山。不变应万变,上午就上线。

通过万能的 API,前端可以定制任何数据、任何结构。
大部分 HTTP 请求后端再也不用写接口了,更不用写文档了。
前端再也不用和后端沟通接口或文档问题了。再也不会被文档各种错误坑了。
后端再也不用为了兼容旧接口写新版接口和文档了。再也不会被前端随时随地没完没了地烦了。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

为什么选择 APIJSON?

  • 解决十大痛点(APIJSON 可大幅提振开发效率、强力杜绝联调扯皮、巧妙规避文档缺陷、非常节省流量带宽等)
  • 开发提速很大(CRUD 零代码热更新全自动,APIJSONBoot 对比 SSM、SSH 等保守估计可提速 20 倍以上)
  • 腾讯官方开源 (使用 GitHub、Gitee、工蜂 等平台的官方账号开源,微信公众号、腾讯云+社区 等官方公告)
  • 社区影响力大 (GitHub 14K+ Star 在 400W+ Java 项目中排名前 100,远超 FLAG, BAT 等国内外绝大部分开源项目)
  • 各项荣誉成就 (腾讯内外 5 个奖项、腾讯开源前九、腾讯后端项目 Star 第一、GitHub Java 日周月榜大满贯 等)
  • 多样用户案例(腾讯内有互娱、音乐、微信、云与智慧等,外部包含华为、华能、百度、快手、中兴、传音、圆通等)
  • 适用场景广泛 (社交聊天、阅读资讯、影音视频、办公学习 等各种 App、网站、公众号、小程序 等非金融类项目)
  • 周边生态丰富(Android, iOS, Web 等各种 Demo、继承 JSON 的海量生态、零代码 接口测试 和 单测试 工具等)
  • 文档视频齐全 (项目介绍、快速上手、安装部署 等后端、前端、客户端的 图文解说、视频教程、代码注释 等)
  • 功能丰富强大 (增删改查、分页排序、分组聚合、各种条件、各种 JOIN、各种子查询、跨库连表 等零代码实现)
  • 使用安全简单(自动增删改查、自动生成文档、自动管理版本、自动控制权限、自动校验参数、自动防SQL注入等)
  • 灵活定制业务 (在后端编写 远程函数,可以拿到 session、version、当前 JSON 对象 等,然后自定义处理)
  • 高质可靠代码(代码严谨规范,商业分析软件源伞 Pinpoint 代码扫描报告平均每行代码 Bug 率低至 0.15%)
  • 兼容各种项目(协议不限 HTTP,与其它库无冲突,对各类 Web 框架集成友好且提供 SpringBoot, JFinal 的 Demo)
  • 工程轻量小巧(仅依赖 fastjson,Jar 仅 280KB,Java 文件仅 59 个共 13719 行代码,例如 APIJSONORM 4.3.1)
  • 多年持续迭代(2016 年至今连续维护 6 年,累计 3000+ 次提交、90+ 次发版、50+ 个贡献者,不断更新迭代中…)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

用户反馈

腾讯 IEG 数据产品开发组负责人 xinlin: “腾讯的 APIJSON 开源方案,它可以做到零代码生成接口和文档,并且整个生成过程是自动化。当企业有数据的时候,马上就可以获得接口”

腾讯科技 后台开发高级工程师 雷大锤: “可以抽出时间来看apijson了,这个可以为T10做准备,也是业界很火的东西,可以提升个人影响力!”

腾讯 bodian520: “在调试GET、POST、PUT接口时遇到了一些问题,把个人的摸索经验分享一下,希望作者能梳理下文档,方便我们更好的接入”

华为 minshiwu: “demo工程,默认使用apijson-framework,可以做到无任何配置即可体验apijson的各种能力。”

字节跳动 qiujunlin: “初次见到这个项目,觉得太惊艳了,眼前一亮。给我的感受是,项目大大简化了开发流程,开发效率提升了很多倍。”

百度智慧城市 lpeng: “很兴奋的发现APIJSON很适合我们的一个开发场景,作为我们协议定义的一部分”

中兴 duyijiang: “感谢腾讯大大提供的框架,很好用”

APIJSON 生态项目

apijson-router 【新】APIJSON 的路由插件,可控地对公网暴露类 RESTful 简单接口,内部转成 APIJSON 格式请求来执行。

apijson-column APIJSON 的字段插件,支持 字段名映射 和 !key 反选字段

hyperf-APIJSON 【新】PHP 版 APIJSON,基于 Hyperf(PHP Swoole),支持 APIJSON 多种关联和多个功能符

APIJSON.NET C# 版 APIJSON,支持大部分 APIJSON 功能,支持 MySQL, PostgreSQL, SQL Server, Oracle, SQLite

apijson-go【新】Go 版 APIJSON , 基于Go(>=1.18) + GoFrame2, 支持查询、单表增删改、权限管理等

apijson-go Go 版 APIJSON,支持 单表查询、列表筛选、关联查询、多个功能符等

apijson-node 字节跳动工程师开源的 Node.ts 版 APIJSON,提供 nestjs 和 typeorm 的 Demo 及后台管理

uliweb-apijson Python 版 APIJSON,支持大部分 APIJSON 功能,支持 MySQL, PostgreSQL, SQL Server, Oracle 等

APIJSONBoot_Hive APIJSON + SpringBoot 连接 Hive, Hadoop 使用的 Demo

apijson-practice【新】BAT 技术专家开源的 APIJSON 参数校验注解 Library 及相关 Demo

APIJSONDemo【新】字节跳动工程师接入 ClickHouse 的 APIJSON 使用 Demo

APIJSONDemo_ClickHouse APIJSON + SpringBoot 连接 ClickHouse 使用的 Demo

apijson-db2 APIJSON 接入 IBM 数据库 DB2 的 Demo

light4j 整合 APIJSON 和微服务框架 light-4j 的 Demo,同时接入了 Redis

apijson-examples 关于 APIJSON 包含 admin, upms, web 的多端 Demo

感谢热心的作者们的贡献,点 ⭐Star 鼓励他们继续完善吧^_^

贡献者们

主项目 APIJSON 的贡献者们(6 个腾讯工程师、1 个微软工程师、1 个阿里云工程师、1 个知乎基础研发架构师、1 个字节跳动工程师、1 个网易工程师、1 个 Zoom 工程师、1 个圆通工程师、1 个智联招聘工程师、1 个美国加州大学学生、3 个 SUSTech 学生等):

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

生态周边项目的作者们(2 个腾讯工程师、1 个 BAT 技术专家、1 个微软工程师、2 个字节跳动工程师、1 个神州数码工程师&Apache dubbo2js 作者 等):

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

感谢大家的贡献。

 

腾讯 APIJSON – 零代码、全功能、强安全 ORM 库

后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构!

https://gitee.com/Tencent/APIJSON

创作不易、坚持更难,右上角点 ⭐Star 支持/收藏下吧 ^_^

 

Torna 1.20.0 发布,本次更新内容如下:

  • 【新增】可自定义扩展i18n(后台管理-系统设置-国际化配置)
  • 【优化】swagger导入支持非ref的嵌套对象
  • 【优化】优化应用配置UI
  • 【优化】调整前端目录结构

1.20.0开始可以扩展i18n配置,前往后台管理-系统设置-国际化配置

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

保存后,用户可在 用户中心-系统设置进行切换

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

关于 Torna

接口文档解决方案,目标是让接口文档管理变得更加方便、快捷。Torna 采用团队协作的方式管理和维护接口文档,将不同形式的文档纳入进来统一维护。

Torna 弥补了传统文档生成工具(如 swagger)的不如之处,在保持原有功能的前提下丰富并增强了一些实用的功能。

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

解决文档管理痛点

  • 不满足 swagger 文档预览页面和调试页面的展现方式
  • 不喜欢 swagger 这种侵入式注解
  • 希望使用 javadoc 注释生成文档,并进行接口调试
  • 希望把公司所有项目接口文档进行统一管理
  • 希望把项目中的若干文档提供给第三方调用者查看
  • 希望可以统一管理项目中的字典枚举

如果您有以上几个需求和痛点,或许可以尝试一下使用 Torna

推荐组合

smart-doc + Torna 实现文档全流程自动化

如果您使用 Java 语言,推荐使用 

smart-doc + Torna 组成行业领先的文档生成和管理解决方案,使用 smart-doc 无侵入完成 Java 源代码和注释提取生成 API 文档,自动将文档推送到 Torna 企业级接口文档管理平台。

通过这套组合您可以实现:只需要写完 Java 注释就能把接口信息推送到 Torna 平台,从而实现接口预览、接口调试。

推送的内容有:

如果您是非 Java 语言,可以使用表单页面编辑以上内容,完成后同样可以进行接口预览、调试。

smart-doc 整合 Torna 图文教程

近日,亚信科技(成都)有限公司(以下简称“亚信安全”)签署openKylin社区CLA(Contributor License Agreement 贡献者许可协议),正式加入openKylin开源社区。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

亚信安全是中国网络安全软件领域的领跑者,是业内“懂网、懂云”的网络安全公司。承继亚信30年互联网建设经验,肩负守护互联网之使命,亚信安全于2015年正式启航,目前已成为建设中国网络安全的重要力量。

亚信安全在云安全、身份安全、终端安全、安全管理、高级威胁治理及 5G 安全等领域突破核心技术,用实力筑牢云、网、边、端之安全防线,在威胁情报、EDR、XDR 等细分技术领域均居于领导者象限,是中国网络安全企业 10 强。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在加入openKylin社区后,亚信安全就将积极参与社区技术共享,聚合更多操作系统和软件厂商之合力,共同进行技术创新和生态共建,迅速丰富上下游软件生态,协同创新,积极贡献全球开源项目,吸引全球开发者加入,在新型平台、运行兼容、智能支撑、安全易用等技术方向不断努力,共同引领新一代科技革命与数字经济的发展。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

社区会员持续招募中

目前,openKylin社区会员招募正在火热进行中,欢迎更多企业伙伴加入,携手共建,打造桌面操作系统顶级社区,推动国产操作系统产业生态健康发展。详情可查看:【https://sigusoft.com/s/yk82DEQSG0knaQNKyc-vsg 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

openKylin(开放麒麟)社区旨在以“共创”为核心,在开源、自愿、平等、协作的基础上,通过开源、开放的方式与企业构建合作伙伴生态体系,共同打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态繁荣发展。

社区首批理事成员单位包括麒麟软件、普华基础软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、心科技、中国电科32所、技德系统、北京麟卓、先进操作系统创新中心等13家产业同仁和行业机构。

 

审核:openKylin

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

作者简介

邓宇星,SUSE Rancher 中国区软件架构师,6 年云原生领域经验,参与Rancher 1.x 到 Rancher 2.x 版本迭代,目前负责 Rancher For openEuler(RFO) 项目开发。

最近我们关注到一个关于 containerd 运行时的 issue,该问题在 containerd v1.6.9/v1.5.15 被引入。出现的问题是,当 containerd 重启后,在其中运行的 Pod 数据中关于网络相关的数据(如 pod ip)丢失,核心原因在于部分数据没有落盘。  

受影响的版本:

  • v1.6.9 ~ v1.6.14,问题在 v1.6.15 版本中被修复。
  • v1.5.15 ~ v1.5.16,问题在 v1.5.17 版本中被修复。

通过以下步骤,可以快速重现该问题,并验证该问题的修复情况。

本文使用 rke2 为例进行演示,版本为 rke2 v1.24.9+rke2r1,该版本使用了 k3s-containerd v1.6.12-k3s1,受该 containerd 问题影响。

在 containerd 的默认行为中,重启 containerd 服务不会影响正在运行的业务容器,并在启动容器时,通过将容器父进程绑定 Pid 1 的方式进行体现。即使使用 systemctl 对服务进行重启,也不会影响到已经在运行的容器状态。

问题重现


至此,rke2 单节点服务启动完成,但我们的目标是 containerd,接下来继续操作:


我们以 metrics-server 的 pod 为例,查询 pod 详情中的网络部分内容,并对 containerd 进行重启,对问题进行重现:


通过新的 terminal,使用 crictl 查询 containerd 运行状态


从最后的返回结果可以看出,containerd 重启后容器的 IP 丢失。

问题影响

通过在上述例子中重启 rke2-server 可以看到,由于 ip 信息丢失,导致了业务容器被重建,带来了业务中断的风险。


可以看到,在 rke2-server 重启后,使用了 cni 的 pod 发生了重启,在 crictl pods 返回中可以看到重新创建的 pods。

问题修复验证

下载新版本 containerd,这次验证使用 k3s-containerd v1.6.14+k3s1。该版本为 Rancher 在 containerd v1.6.15 发布前紧急发布的修复补丁版本。


通过新的 terminal,使用 crictl 查询 containerd 运行状态


可以看到 containerd 重启后,pod ip 没有丢失。

RKE2 与 RFO

RKE2 以下版本受该 issue 影响:

  • v1.23.15+rke2r1
  • v1.24.9+rke2r1
  • v1.25.5+rke2r1
  • v1.26.0+rke2r1

该 issue 在 2022 年 12 月 20 日被提交,RKE2 团队在 2023 年 1 月 6 日紧急合并了 containerd 中修复该 issue 的 commit,发布了 k3s-containerd v1.6.14+k3s1 版本,并发布了新的 rke2 rc 版本进行测试验证。  

最终在 1 月 11 日,RKE2 团队发布以下已经修复 containerd 问题的版本:

  • v1.23.16+rke2r1
  • v1.24.9+rke2r2
  • v1.25.5+rke2r2
  • v1.26.0+rke2r2

RFO 是 Rancher For openEuler 的缩写,顾名思义,目的在于面向 openEuler 打造 Rancher 基础平台。  

由于 RFO 版本发布周期在 RKE2 之后,RFO 并没有受到该 issue 影响,并在近期发布了以下版本:

  • v1.23.16+rfor1
  • v1.24.9+rfor1
  • v1.24.10+rfor1
  • v1.25.5+rfor1
  • v1.25.6+rfor1
  • v1.26.0+rfor1
  • v1.26.1+rfor1

写在最后

由于操作系统的软件包发布存在一定的时间延后性,在大部分情况下都无法及时修复软件出现的问题。像 CVE、功能缺陷等问题都比较紧急,等待操作系统供应商提供修复版本将是一个漫长的过程,甚至有时候由于一些限制,操作系统提供商无法提供新版本的软件包,这会给系统运行带来不确定因素。

在这种情况下,将软件自身依赖的组件打包到自己的 rootfs 中进行分发,能更好地对其进行管理和升级,避免给系统运行带来风险以及潜在的损失。

关于 RFO 的项目说明和部署使用,请《Rancher RFO 正式 GA》。

作者:闵大为(天未)

从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行了描绘和微调。

从技术的角度已经有很多好的总结,本文会换一种角度思考,既然设计模式研究的是类与类的关系,我们作为工作的个体,一些工作中的策略是不是也可以进行类比,可以更好地去思考这些模式?答案是肯定的。

创建型模式 5

抽象工厂(Abstract Factory):多套方案

抽象工厂模式是对创建不同的产品类型的抽象。对应到工作中,我们的确应该具备提供多套方案的能力,这也是我们常说的,要提供选择题。当你有这样的前瞻意识,一般也会被打上思考较多的标签,但是内在来说,的确想问题更加全面了。

1.png

生成器(Builder):善于分解

生成器模式是对一个个体的创建过程进行细分,拆解为不同的创建部分。这个对应到工作中,作为一些项目管理人员或者团队管理者,需要将一个大泥球一样的事务,合理分解,让大家各司其职,充分发挥才能。同样,我们对日常的工作内容,也可以按照结构去进行划分,从而更有条理。

2.png

工厂方法(Factory Method):抽象思考

工厂方法模式是说将提供某一产品的过程进行抽象,通过接口的模式去规范出来。类似的,我们很多做事的过程,都是面向过程,没有抽象提炼一下。如果经过进一步思考,那么可以往上再提炼一个层次,发现事物的本质:到底在做什么,我们的职责是什么,提供什么样的价值。想的更清楚,做的也会更加准确。

3.png

原型(Prototype):传承知识

原型模式是说,利用拷贝对象的方法,减少一些复杂的创建过程。这里我们能够学到的是,需要做好日常的积累,很多方案不是每次来都重写,是可以在原来的方案上进行拷贝复用的。这个clone的过程,往往也是知识传承的过程。如果有比较好的传承机制,那么会大大提升服务效率。

4.png

单件(Singleton):专注

单件模式是说在多线程的情况下,要保证对象只创建一遍,作为独一无二的资源。这个我觉得,应该去review一下我们的工作模式,虽然我们常常要并发很多事情,但是如果处处被打断,每件事都想干好,那么可能每件事都干不好。我们要确保在某个时间段竭力地做好一件事。事件是一件件有效解决的,不是一起慢慢解决的。

5.png

结构性模式 7

适配器(Adapter):适应能力

适配器是为了结合原来的能力,适配新的接口服务,比如适配不同的协议入口。工作的时候,其实需要适应不同的人和事,有不同的工作方法方式,但是我们的核心能力是一样的,都是解决对应的问题域。

6.png

桥接(Bridge):合理关系

桥接模式是将原来相互依赖的部分,通过上层接口再往抽象层提一下,减少类之间的直接合作,形成间接关系。这个到对应到工作中来说,有一种场景是,常常开发对开发去case by case解决问题。如果往产品逻辑层走一下,开发对产品,产品层面可能有更好的抽象。当然为了更好的服务体验,这样的解耦是不多见的,但是这样的思考我们可能要get一下。

7.png

组合(Composite):递归思考

组合模式通过继承和孩子节点,可以递归地去描述一个对象层次。这个对我们工作来说,要加深思考的层次,可以某个点拆开去再去思考,同时如果能够在递归分解过程中抽象一些共性的点,就能找到一些规律。比如我们的需求分解,每个需求可以分解为子需求,子需求再往下看又可以递归分解。分解完之后,每个部分有这部分的owner去驱动他的下游,形成一个层次结构。

8.png

装饰(Decorator):增量价值

装饰模式是将原来的能力进行包装,并提供新的行为。其实每次功能迭代,我们大多是在原来的基础上添加新的功能。我们要定义好新的能力,首要前提是继承、理解好原来的逻辑。这里还想提的是,很多时候,我们只看到了我们复用了庞大的基础能力,但是也要看到我们在项目中增量的贡献,这是我们的闪光点。不要把“拧螺丝”真的看成了拧螺丝。

9.png

外观(Facade):深入浅出

外观模式是说我们不需要理解复杂的系统,而是通过一个外观去操作。这里我们的工作思路是,我们不用展示复杂的细节,我们要提供一些高层的理解,汇报如此,系统的包装也是如此。就比如,服务功能孤立来看,可能很多、很杂,但如果有一个统一的站点去引导包装,那么感觉会好很多,也会看上去有点收口和聚焦的感觉。

10.png

享(Flyweight):善于链接

享模式是说,当我们已经存在一些内容的时候,可以通过缓存复用,而不是重新创建,减少开销。我们在工作中也要做好积累,但是更要做好缓存的key,通过怎么样的手段去链接到我们的工作中,是需要我们做好类目管理和持续积累的。

11.png

代理(Proxy):理解保护

代理是为了包装一个类,对相关操作进行二次转发或者进行一些管控。工作中来说,有些工作模式下,有时候我们可能会抱怨管理者代理了我们的决策等操作,但是换个角度想,他们保护了你不用直接被暴露在业务方侧,能够按照预期内的节奏提供服务,不会被主动设置一些预期外操作或私活。

12.png

行为型模式 11

责任链(Chain of Responsibility):能力与责任

责任链是说将请求让队列内的处理器一个个执行,直到找到可以执行的。这里对我们工作的启示是,我们常常抱怨我们得到的机会少,不能成为队列内优先可以处理的处理器,总是处理人家不需要的。但是换个角度看,首先责任链里面的处理器应该是正交的,大家应该各司其职。退一步来说,如果真的有重叠,那么你应该努力提升自己,成为能力强的,从而提高队列内的优先级。

13.png

命令(Command):加强合作

命令模型是说将请求包装为命令,这样在执行的时候可以与具体的执行逻辑解耦。工作中来说,我们有时候不应该太关心一个事情是怎么完成的,当交给别人完成时,信任他们即可,就是从解决问题的角度来看,不用事事亲为,事事较真。但是这并不妨碍我们主动养成全局视角,了解每个细节。合作才能影响更多的事情。

14.png

解释器(Interpreter):加强理解

解释器模式是说针对一套上下文,形成一套语言,可以通过解释表达式含义的方式完成对应的任务。这里来说,我们可以形成某个团体的领域语言,内部交流通过相关领域语言交流,可以增加交流效率。此外,其实不同层次都有不同层次的专业术语,有时候一个术语的解释是一个方面的顿悟,还是要多了解工作内容本身。

15.png

迭代器(Iterator):横向职责

迭代器模式是将集合的访问功能独立出来,通过迭代的模式去访问。这种独立职责的操作,工作中我们常常会看到,我们会将需求管理,缺陷管理,资金安全的一些事情独立出来看。一个方面是这些功能块从主体来说是比较内聚的,另一个来方面说,对工作职责的细分,可以让大家把自己的事情干好,发挥团队作战的效能:开发把开发干好,测试把测试干好,资损防护同学把资损防护干好,整体也就做好了。

16.png

中介者(Mediator):协调能力

中介模式是说:当多个类之间要协调的时候,往往引入中介者进行协调,减少大家的知识成本。这个我们常常需要一些PM、PMO这样的角色去管理项目,系统中也需要一些协调层去协调各个域。因此我们也注重培养协调事务、具备全局观的能力。

17.png

备忘录(Memento):小步快跑

备忘录模式是对操作的一些记录,已被可以恢复到之前的版本。在日常工作中,我们常常需要及时备份、及时保存、及时提交等操作,这样在程序崩溃的时候可以快速恢复到之前版本。但从抽象来说,一些比较长时费力的事情,我们应该分解来做,及时锁住部分收益。

18.png

观察者(Observer):主观能动性

观察者模式是说我们通过注册、回掉这样的协作设计,完成变化通知的协作机制。这个工作中来说,换个角度思考,我们可以将一些被动的工作,变成主动的思考。比如:我需要干某部分工作,从工作的角度来说,不得不做,从主动的角度来说,就是需要培养某块的能力。如果对工作内容不太满意,也可以沟通协调,而不是事后爆发,凡是都是可以主观驱动的。

19.png

状态(State):管理自己

状态模式是说在不同的状态下,有不同的处理行为。对工作中来说,我们可能有状态好的时候,有状态不好的时候,主观的处理的手段是调整状态。但是如果调整不过来,我们应该进行不同的操作。比如,脑子好的时候,想一些复杂问题;脑子嗡嗡的时候,做一些简单整理。

20.png

策略(Strategy):理解决策

策略模式是说完成一个事情有不同的算法,可以进行相关切换。我们在工作中,常常会提供不同的方案,不同的方案有不同的成本和收益,但是这些方案的选择时候,往往不是我们能决定的,而是客户client主动判断的。

21.png

模板(Template):标准化能力

模版模式是说对一个执行过程进行抽象分解,通过骨架和扩展方法完成一个标准的主体逻辑和扩展。我们很多时候,做xxx平台也都是这样的:对过程进行标准化,对变化进行定义,形成一个平台逻辑和业务扩展,完成一个产品模版。只是说这个模版是站点,还是扩展点,还是其他的展示形式。这样标准化的能力也是需要长期训练的。

22.png

访问者(Visitor):学会放手

访问者模式是说把对素的访问操作交给访问者来操作,因为对访问者来说常常有不同的访问行为。在工作中,往往我们只能陈述事实,这个内容消化后,每个人都有自己的理解。代码协作也是一样,比如:页面到底长什么样,其实还是要交还给业务本身,我们应该专注于提供基础的能力。

23.png

总结

作为开发者,我们对于如何写出优雅的代码,表示疑惑。因为常常背后是复杂的问题域,优雅的设计往往产生于局部,很难整体都很优雅。

作为工作者,我们对于如何做出好的表现,表示疑惑。因为背后常常是综合素质与机遇的结合,好的结果往往产生于一个阶段,长期需要较快且持续的成长。

但是,如果我们有一些指导性的原则,往往我们能够明白事务的折中点,做出更加合理的设计,以及更加关键的贡献。

Apache APISIX Ingress Controller 是一款以 Apache APISIX 作为数据面的 Kubernetes Ingress Controller 开源工具,目前已经更新到 v1.3 版本,实现了如证书管理、负载均衡、金丝雀发布等功能。

长久以来,证书管理都不是一件简单的事情,虽然 Apache APISIX Ingress Controller 支持从 Kubernetes Secrets 资源中提取证书和私钥,并转换为 Apache APISIX 可识别的 SSL 对象,但这只是整个证书管理链中的一部分,证书的颁发、轮转、吊销逻辑依然需要管理员执行,尤其当证书数量比较多时,工作量往往并不小,因而会占用管理员不少的时间。

Cert Manager 是一款致力于在 Kubernetes 平台上简化证书管理的软件,它支持对接许多不同的证书源,如 Let’s Encrypt 和 HashiCorp Vault。

如果你在使用 Apache APISIX Ingress Controller 时,遇到了证书管理的麻烦,那么使用 Cert Manager 将会是一个不错的选择,本文将介绍如何通过 Cert Manager 来创建证书并对接到 Apache APISIX Ingress Controller。

步骤一:环境准备

如果你希望按照本文的指导进行实际的操作,请确保以下环境和工具已准备就绪:

  1. 准备一个可用的 Kubernetes 集群,开发环境中,你可以使用 Kind 和 Minikube
  2. 安装 kubectl
  3. 安装 Helm v3

请注意,下文所有的操作都将在 ingress-apisix 命名空间中执行,因此需要先创建该命名空间:

步骤二:安装 Apache APISIX Ingress Controller

我们可以通过 Helm 来安装 Apache APISIX Ingress Controller,包括数据面的 Apache APISIX 和 etcd 集群。


查看详细安装介绍。

步骤三:安装 Cert Manager

通过 Helm 来安装 Cert Manager,可查看详细安装介绍。


安装完毕后请等待一会后查看组件的运行状态,确保所有组件都已正常运行,你可以通过如下命令进行查看。


返回结果如下所示,表示所有组件都已正常运行。


Kubernetes Controller Manager 的机制决定了 Pod 名称会有所不同。

步骤四:申请证书并测试

首先我们需要配置证书颁发对象。


并创建自签名证书颁发者。


请注意,自签名颁发对象不推荐使用在生产环境中!更多证书颁发对象的配置请参考这里。 然后为域名 创建一张证书。


此时需要查看对应 Secrets 是否已经被创建。


通过上述验证,该 Secrets 对象的创建事件已经被 Apache APISIX Ingress Controller 捕获到,我们尝试访问 Apache APISIX Ingress Controller 来验证证书是否生效,首先我们需要创建额外的路由对象。


接下来访问服务 。注意,默认情况下该服务的类型为 ,你可以根据需要修改其类型,比如你的 Kubernetes 集群是云厂商托管的,则可以考虑将其修改为 类型,以获取一个外部可达的 IP。

这里我们通过端口转发的方式将服务映射到本地。


然后开始配置访问。


经过上述操作,可以看到访问成功,说明证书已经生效。注意,由于证书是自签名的,这里需要加上 选项来忽略证书的校验。

此外,如果你想要轮转证书,删除 这一 Secret 对象即可,Cert Manager 会立刻创建一个新的 httpbin Secret 对象,并且包含新的证书。

总结

本文主要讲解了如何利用 Cert Manager 在 Apache APISIX Ingress Controller 中进行证书的创建和管理。想了解更多关于 Apache APISIX Ingress 的介绍与内容,可参考本篇文章 或者参与 Apache APISIX Ingress 项目每两周举行的线上讨论,分享当下项目进度、最佳实践及设计思路等多个话题,可查看具体 issue 了解更多。

谷歌宣布推出与 ChatGPT 竞争的 AI 产品 Bard 后,百度微信公众号今日也官宣介绍了该公司的大模型新项目 —— 文心一言(英文名 ERNIE Bot)。公告注释称:

①.百度在人工智能四层架构中,有全栈布局。包括底层的芯片、深度学习框架、大模型以及最上层的搜索等应用。文心一言,位于模型层。②.百度在人工智能领域深耕数十年,拥有产业级知识增强文心大模型 ERNIE ,具备跨模态、跨语言的深度语义理解与生成能力。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布) 

值得寻味的是,这不过百字的公告内容却有着四位责任编辑,且还都采用了统一的 ABB 命名格式:希加加、度晓晓、叶悠悠、林开开对此网友纷纷猜测这些其实是数字人,更有甚者还提出这篇文章说不定就是采用文心一言写的。

据百度公司向澎湃科技确认称,文心一言计划于今年 3 月完成内测,面向公众开放。目前,文心一言在做上线前的冲刺。而按照谷歌和微软加快推出类 ChatGPT 服务的节奏,文心一言开放内测还有可能提前。“ChatGPT 是人工智能里程碑,更是分水岭,这意味着 AI 技术发展到临界点,企业需要尽早布局。”

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

MyCms 是一款基于 Laravel 开发的开源免费的开源多语言商城 CMS 企业建站系统。

MyCms 基于 Apache2.0 开源协议发布,免费且可商业使用,欢迎持续关注我们。

v4.3 更新内容

1、优化后台模板
2、新增公众号微信支付
3、优化广告插件
4、模板增加全局会员变量
5、模板增加多语言适配URL函数
6、修正 AdminComposer
7、优化获取广告函数返回值
8、修正fast curd 列表页母模板工具按钮
9、后台列表增加图片显示支持
10、适配后台列表带参数操作URL
11、增加获取URL参数js方法
12、增加拼接URL参数js方法
13、新增多语言后台控制器增加继承字段支持
14、优化 fast curd 编辑页母模板
15、修正提交表单无法获取富文本内容
16、修正多语言商品添加
17、优化后台表单提交后返回上一个页面
18、添加/编辑商品增加事务
19、优化删除商品时删除相关数据
20、修正规格表自增数解决商品规格冲突
21、增加商品服务类,并增加 goods 别名
22、修正自定义页面路径问题

后台部分页面截图

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

站点地址

  • 官方网站 : https://www.mycms.net.cn/

  • 使用手册:https://www.mycms.net.cn/shouce

  • 二次开发:https://www.mycms.net.cn/dev

  • API 文档:https://www.mycms.net.cn/api-doc

  • 模板下载:https://www.mycms.net.cn/muban

  • 演示后台 : https://demo.mycms.net.cn/system/login

  • 演示后台:admin /admin

优秀案例

  • 在线计算网 : https://www.zaixianjisuan.com/
  • 程序员导航 : https://nav.mycms.net.cn/
  • 古诗词网 : https://www.gushici.top/
  • 火马活码:https://www.huomahuoma.com/

VirtualEnv 20.18.0 现已发布,VirtualEnv 用于在一台机器上创建多个独立的 Python 运行环境,可隔离项目之间的第三方包依赖,为部署应用提供方便,把开发环境的虚拟环境打包到生产环境即可,不需要在服务器上再折腾一翻。 

新版更新内容如下:

  • release 20.17.1 #2462
  • 将 pypa/gh-action-pypi-publish 从 1.6.1 升级到 1.6.3 #2464
  • 将 pypa/gh-action-pypi-publish 从 1.6.3 升级到 1.6.4 #2465
  • 修复 Nushell 的安装故障 #2475
  • 迁移到 hatchling,放弃 3.6 的支持 #2474
  • 修复 coverage reporting #2477
  • 修复 Nushell 激活脚本中的错误提示 #2481
  • 不要在 forks 上运行预定的工作流作业 #2490
  • 完善 activator 文档 #2488
  • 升级嵌入式 pip 和 setuptools #2489
  • 使用 furo 文档主题 #2496

更新说明:https://github.com/pypa/virtualenv/releases/tag/20.18.0

AI 驱动的语义搜索应用 txtai 已发布 5.3 版本,此版本添加了嵌入引导和提示驱动的搜索,以及多种训练语言模型的方法。

提示驱动的搜索是 txtai 中会话搜索的一大进步,它可以将复杂的提示传递给 txtai ,以自定义返回搜索结果的方式。另外,现在支持从头开始培训语言模型。支持屏蔽语言建模 (MLM)、因果语言建模 (CLM) 和替换标记检测(ELECTRA 风格),同属微型模型工作的一部分。

txtai 是一个人工智能驱动的搜索引擎,可以在文本的各个部分上建立一个 AI 驱动的索引。 txtai 支持构建文本索引以执行相似性搜索并创建基于问 – 答的系统。此外,txtai 还具有用于 zero-shot 分类的功能。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

新功能

  • 将语言建模任务添加到 HFTrainer ( #403 )
  • 添加语言建模示例笔记本(#408 
  • 将常见问题解答部分添加到文档 ( #413 )
  • 将语言生成任务添加到 HFTrainer ( #414 )
  • 向 HFTrainer 添加替换标记检测任务(#415 
  • 添加用于文本生成的生成器管道 ( #416 )
  • 添加用于 LLM 的嵌入引导和提示驱动搜索的笔记本 ( #418 )

改进

  • 标准化 BM25 和 TF-IDF 分数(#401 
  • 如果在 Google Colab 中运行,请添加注释以重新启动内核 – 谢谢@hsm207!( #410 )
  • 启动 API 和找不到配置文件时添加清除错误(#412 
  • 提取器管道 2.0 ( #417 )
  • 使文本参数对于应用程序中的提取器管道是可选的(#420 

Bug修复

  • 修复 ORDER BY 区分大小写的问题(#405 

 更新公告:https://github.com/neuml/txtai/releases/tag/v5.3.0

 

SparkyLinux 6.6 已正式发布,这是 SparkyLinux 6 “Po Tolo” 系列的第六次维护更新和 ISO 版本。

SparkyLinux 6.6 版本同步了 Debian 11.6“Bullseye”版本的软件存储库,由 Linux 内核 5.10.166 LTS 提供支持,还提供对最新的 Linux 6.1 内核的支持,可以与 SparkyLinux 不稳定存储库中的 Linux 内核 5.10 LTS 一起安装。另一方面,ARM 映像随 Linux 内核 5.15.84 一起提供。

此版本更新了用于创建实时 USB 磁盘的 SparkyLinux 内部构建工具 (sparky-live-usb-creator),支持持久存储。通过此功能可直接从 USB 磁盘使用 SparkyLinux 实时系统,并将安装的软件包保存在可启动媒体上。此外,SparkyLinux 6.6 对 GRUB 和 ISOLINUX 引导加载程序的实时引导列表进行了细微更改,以使其与上述持久性功能兼容。

软件层面,SparkyLinux 6.6 带有 LXQt 0.16.0、Xfce 4.16、KDE ​​Plasma 5.20.5 和 Openbox 3.6.1 (MinimalGUI) 图形环境,附带新的应用程序,如 Mozilla Firefox 102.7.0 ESR 浏览器, Mozilla Thunderbird 102.6.0 电子邮件客户端和 LibreOffice 7.0.4 办公套件等。

SparkyLinux 6 用户不需要下载新的 ISO ,只需使用系统升级 ( sparky-upgrade ) 工具或在终端仿真器应用程序中运行 sudo apt update && sudo apt full-upgrade 命令来安装最新更新。

更新公告:https://sparkylinux.org/sparky-6-6/

CotEditor 是一个轻量级、简洁、但功能强大的文本编辑器,用于编辑纯文本文件,如网页 HTML、CSS),程序源代码(Python、Ruby、Perl 等),结构化文本(Markdown、Textile、Tex 等)或任何其他类型的纯文本。

CotEditor 4.4.5 正式发布,该版本更新内容如下:

系统要求

  • macOS 12 及以上版本

新功能

  • 在打印页眉/页脚选项中增加 “最后修改日期” 选项
  • 在行尾不一致的提示中增加 “忽略” 选项

改进

  • [dev] 将 Yams 从 5.0.3 更新到 5.0.4

修复

  • 修复打印页眉/页脚对齐选项与所选设置不一致的问题
  • 修复一个问题,即一些快捷键可能被用于菜单键绑定定制而没有警告,即使它们被用于现有的命令
  • 修复查找窗口中丢失的本地化
  • 移除键绑定窗格中过时的描述

更多详情可查看:https://github.com/coteditor/CotEditor/releases/tag/4.4.5

SQLAlchemy 2.0.2 已发布,更新内容主要是关于声明式注释 (Declarative Annotations) 功能的改进和错误修复。

此外,该版本还修复了一个特殊 bug:在 asyncio 下使用 asyncpg 数据库驱动时发现的连接池问题。当连接池中的连接没有正确返回到连接池中时,连接池没有反馈此情况,该问题已经被修复。

详情查看 Changelog。

下载地址:https://www.sqlalchemy.org/download.html

SQLAlchemy 2.0 是一个非常大的版本更新,它有两个迁移指南:

  • Major Migration Guide:介绍了如何使应用程序达到 API 兼容性,以便能够在 SQLAlchemy 1.4 或 2.0 中同等运行
  • SQLAlchemy 2.0 新功能:提供了应用程序在 SQLAlchemy 2.0 上运行后可用的所有新功能和 API。

延伸阅读

  • SQLAlchemy 2.0.0 正式发布,Python ORM 框架

mypy 是 Python 静态类型检查器,旨在结合动态类型和静态类型的优点,将 Python 的表现力和便利性与强大的类型系统和编译时 (compile-time) 类型检查相结合,提供编译时的类型检查和高效地编译为原生代码,无需使用重量级和耗费 runtime 开销的 Python 虚拟机。

近日,mypy 正式发布了 1.0 版本,引入了新特性、优化了性能以及修复错误等。

主要变化

  • 采用新的版本号命名规则

由于 mypy 版本号已进入 1.0 阶段,因此开发团队决定切换到新的版本号命名规则,新规则将采用 x.y.z. 格式:

  • 如果功能版本包含影响大部分用户的重大向后不兼容性变更,则主版本号 (x) 会递增
  • 每个功能版本都会增加次要版本号 (y)
  • 当仅存在修复时,小版本号 (z) 会递增

详细说明。

  • 优化性能

团队介绍道,在检查 Dropbox 内部代码库时,他们发现 mypy 1.0 的速度比 mypy 0.991 快 40%。他们还设置了一个日常工作来衡量 mypy 最新开发版本的性能,以便更容易跟踪性能变化。

部分优化项包括:

  • 提升具备许多属性的类错误的性能
  • 加速 make_simplified_union
  • 针对语义分析器的微优化
  • 加速递归类型检查
  • 加速刷新类型变量
  • 通过避免嵌套函数优化子类型检查
  • 优化子类型检查中的类型参数检查

点此查看详情。

  • 支持”self”类型

现在有一个更简单的语法来声明 PEP 673 中引入的通用 self 类型:Self 类型。开发者不再需要定义类型变量来使用”self”类型,并且可以将它们与属性搭配使用。mypy 文档中的示例:

 

详细更新说明查看发布公告。

时隔四周,Chrome 新版本如约而至,Chrome 110 版带来了对翻译、密码管理、Nvidia RTX Super Resolution 等功能的改进与支持,并且从该版本起 Chrome 将不再支持 Windows 7 和 8.1 系统,如需使用最新版本 Chrome 浏览器,需要将系统最低升级至 Windows 10。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Google 翻译

Chrome 内置了 Google 出色的翻译服务,但想要改变翻译功能的某些设置一直都比较复杂。以前最简单的选择是访问一个外语网页,一旦出现 Google 翻译的弹出窗口,就可以在那里调整设置。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

现在 Chrome 在这方面做得更好,可以直接在浏览器设置中的 “语言” 标签下找到 Google 翻译的选项,也可以通过在地址栏中访问 “chrome://settings/languages” 来查阅设置。

安全浏览

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Google 在 Chrome 中提供了一些功能来确保安全浏览。在 Chrome 110 中,你可以将安全功能再提升一个层次。每当一个网站或浏览器扩展程序提出 cookie 请求时,你都可以获得分析,以检查是否存在任何恶意软件。

Nvidia RTX Super Resolution

Nvidia RTX Super Resolution 是一种可以在浏览器中提升视频质量的技术。该功能仅适用于 Nvidia 的 30 和 40 系列 GPU。例如,如果你有一台 4K 显示器,该技术可以直接在网络播放器中将视频从 1080p 升级到 4K。

停止支持 Windows 7 和 8.1

Chrome 110 是第一个不再支持 Windows 7 和 8.1 的 Chrome 浏览器版本。Google 对这两个较旧的 Windows 操作系统的支持随着 Chrome 109 的发布而结束。

密码管理器改进

Chrome 的密码管理器得到一项改进,现在用户可以使用生物识别方法在浏览器中自动填充密码。

更多详情可查看:https://developer.chrome.com/blog/new-in-chrome-110/

作者:闵大为(天未)

从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行了描绘和微调。

从技术的角度已经有很多好的总结,本文会换一种角度思考,既然设计模式研究的是类与类的关系,我们作为工作的个体,一些工作中的策略是不是也可以进行类比,可以更好地去思考这些模式?答案是肯定的。

创建型模式 5

抽象工厂(Abstract Factory):多套方案

抽象工厂模式是对创建不同的产品类型的抽象。对应到工作中,我们的确应该具备提供多套方案的能力,这也是我们常说的,要提供选择题。当你有这样的前瞻意识,一般也会被打上思考较多的标签,但是内在来说,的确想问题更加全面了。

1.png

生成器(Builder):善于分解

生成器模式是对一个个体的创建过程进行细分,拆解为不同的创建部分。这个对应到工作中,作为一些项目管理人员或者团队管理者,需要将一个大泥球一样的事务,合理分解,让大家各司其职,充分发挥才能。同样,我们对日常的工作内容,也可以按照结构去进行划分,从而更有条理。

2.png

工厂方法(Factory Method):抽象思考

工厂方法模式是说将提供某一产品的过程进行抽象,通过接口的模式去规范出来。类似的,我们很多做事的过程,都是面向过程,没有抽象提炼一下。如果经过进一步思考,那么可以往上再提炼一个层次,发现事物的本质:到底在做什么,我们的职责是什么,提供什么样的价值。想的更清楚,做的也会更加准确。

3.png

原型(Prototype):传承知识

原型模式是说,利用拷贝对象的方法,减少一些复杂的创建过程。这里我们能够学到的是,需要做好日常的积累,很多方案不是每次来都重写,是可以在原来的方案上进行拷贝复用的。这个clone的过程,往往也是知识传承的过程。如果有比较好的传承机制,那么会大大提升服务效率。

4.png

单件(Singleton):专注

单件模式是说在多线程的情况下,要保证对象只创建一遍,作为独一无二的资源。这个我觉得,应该去review一下我们的工作模式,虽然我们常常要并发很多事情,但是如果处处被打断,每件事都想干好,那么可能每件事都干不好。我们要确保在某个时间段竭力地做好一件事。事件是一件件有效解决的,不是一起慢慢解决的。

5.png

结构性模式 7

适配器(Adapter):适应能力

适配器是为了结合原来的能力,适配新的接口服务,比如适配不同的协议入口。工作的时候,其实需要适应不同的人和事,有不同的工作方法方式,但是我们的核心能力是一样的,都是解决对应的问题域。

6.png

桥接(Bridge):合理关系

桥接模式是将原来相互依赖的部分,通过上层接口再往抽象层提一下,减少类之间的直接合作,形成间接关系。这个到对应到工作中来说,有一种场景是,常常开发对开发去case by case解决问题。如果往产品逻辑层走一下,开发对产品,产品层面可能有更好的抽象。当然为了更好的服务体验,这样的解耦是不多见的,但是这样的思考我们可能要get一下。

7.png

组合(Composite):递归思考

组合模式通过继承和孩子节点,可以递归地去描述一个对象层次。这个对我们工作来说,要加深思考的层次,可以某个点拆开去再去思考,同时如果能够在递归分解过程中抽象一些共性的点,就能找到一些规律。比如我们的需求分解,每个需求可以分解为子需求,子需求再往下看又可以递归分解。分解完之后,每个部分有这部分的owner去驱动他的下游,形成一个层次结构。

8.png

装饰(Decorator):增量价值

装饰模式是将原来的能力进行包装,并提供新的行为。其实每次功能迭代,我们大多是在原来的基础上添加新的功能。我们要定义好新的能力,首要前提是继承、理解好原来的逻辑。这里还想提的是,很多时候,我们只看到了我们复用了庞大的基础能力,但是也要看到我们在项目中增量的贡献,这是我们的闪光点。不要把“拧螺丝”真的看成了拧螺丝。

9.png

外观(Facade):深入浅出

外观模式是说我们不需要理解复杂的系统,而是通过一个外观去操作。这里我们的工作思路是,我们不用展示复杂的细节,我们要提供一些高层的理解,汇报如此,系统的包装也是如此。就比如,服务功能孤立来看,可能很多、很杂,但如果有一个统一的站点去引导包装,那么感觉会好很多,也会看上去有点收口和聚焦的感觉。

10.png

享(Flyweight):善于链接

享模式是说,当我们已经存在一些内容的时候,可以通过缓存复用,而不是重新创建,减少开销。我们在工作中也要做好积累,但是更要做好缓存的key,通过怎么样的手段去链接到我们的工作中,是需要我们做好类目管理和持续积累的。

11.png

代理(Proxy):理解保护

代理是为了包装一个类,对相关操作进行二次转发或者进行一些管控。工作中来说,有些工作模式下,有时候我们可能会抱怨管理者代理了我们的决策等操作,但是换个角度想,他们保护了你不用直接被暴露在业务方侧,能够按照预期内的节奏提供服务,不会被主动设置一些预期外操作或私活。

12.png

行为型模式 11

责任链(Chain of Responsibility):能力与责任

责任链是说将请求让队列内的处理器一个个执行,直到找到可以执行的。这里对我们工作的启示是,我们常常抱怨我们得到的机会少,不能成为队列内优先可以处理的处理器,总是处理人家不需要的。但是换个角度看,首先责任链里面的处理器应该是正交的,大家应该各司其职。退一步来说,如果真的有重叠,那么你应该努力提升自己,成为能力强的,从而提高队列内的优先级。

13.png

命令(Command):加强合作

命令模型是说将请求包装为命令,这样在执行的时候可以与具体的执行逻辑解耦。工作中来说,我们有时候不应该太关心一个事情是怎么完成的,当交给别人完成时,信任他们即可,就是从解决问题的角度来看,不用事事亲为,事事较真。但是这并不妨碍我们主动养成全局视角,了解每个细节。合作才能影响更多的事情。

14.png

解释器(Interpreter):加强理解

解释器模式是说针对一套上下文,形成一套语言,可以通过解释表达式含义的方式完成对应的任务。这里来说,我们可以形成某个团体的领域语言,内部交流通过相关领域语言交流,可以增加交流效率。此外,其实不同层次都有不同层次的专业术语,有时候一个术语的解释是一个方面的顿悟,还是要多了解工作内容本身。

15.png

迭代器(Iterator):横向职责

迭代器模式是将集合的访问功能独立出来,通过迭代的模式去访问。这种独立职责的操作,工作中我们常常会看到,我们会将需求管理,缺陷管理,资金安全的一些事情独立出来看。一个方面是这些功能块从主体来说是比较内聚的,另一个来方面说,对工作职责的细分,可以让大家把自己的事情干好,发挥团队作战的效能:开发把开发干好,测试把测试干好,资损防护同学把资损防护干好,整体也就做好了。

16.png

中介者(Mediator):协调能力

中介模式是说:当多个类之间要协调的时候,往往引入中介者进行协调,减少大家的知识成本。这个我们常常需要一些PM、PMO这样的角色去管理项目,系统中也需要一些协调层去协调各个域。因此我们也注重培养协调事务、具备全局观的能力。

17.png

备忘录(Memento):小步快跑

备忘录模式是对操作的一些记录,已被可以恢复到之前的版本。在日常工作中,我们常常需要及时备份、及时保存、及时提交等操作,这样在程序崩溃的时候可以快速恢复到之前版本。但从抽象来说,一些比较长时费力的事情,我们应该分解来做,及时锁住部分收益。

18.png

观察者(Observer):主观能动性

观察者模式是说我们通过注册、回掉这样的协作设计,完成变化通知的协作机制。这个工作中来说,换个角度思考,我们可以将一些被动的工作,变成主动的思考。比如:我需要干某部分工作,从工作的角度来说,不得不做,从主动的角度来说,就是需要培养某块的能力。如果对工作内容不太满意,也可以沟通协调,而不是事后爆发,凡是都是可以主观驱动的。

19.png

状态(State):管理自己

状态模式是说在不同的状态下,有不同的处理行为。对工作中来说,我们可能有状态好的时候,有状态不好的时候,主观的处理的手段是调整状态。但是如果调整不过来,我们应该进行不同的操作。比如,脑子好的时候,想一些复杂问题;脑子嗡嗡的时候,做一些简单整理。

20.png

策略(Strategy):理解决策

策略模式是说完成一个事情有不同的算法,可以进行相关切换。我们在工作中,常常会提供不同的方案,不同的方案有不同的成本和收益,但是这些方案的选择时候,往往不是我们能决定的,而是客户client主动判断的。

21.png

模板(Template):标准化能力

模版模式是说对一个执行过程进行抽象分解,通过骨架和扩展方法完成一个标准的主体逻辑和扩展。我们很多时候,做xxx平台也都是这样的:对过程进行标准化,对变化进行定义,形成一个平台逻辑和业务扩展,完成一个产品模版。只是说这个模版是站点,还是扩展点,还是其他的展示形式。这样标准化的能力也是需要长期训练的。

22.png

访问者(Visitor):学会放手

访问者模式是说把对素的访问操作交给访问者来操作,因为对访问者来说常常有不同的访问行为。在工作中,往往我们只能陈述事实,这个内容消化后,每个人都有自己的理解。代码协作也是一样,比如:页面到底长什么样,其实还是要交还给业务本身,我们应该专注于提供基础的能力。

23.png

总结

作为开发者,我们对于如何写出优雅的代码,表示疑惑。因为常常背后是复杂的问题域,优雅的设计往往产生于局部,很难整体都很优雅。

作为工作者,我们对于如何做出好的表现,表示疑惑。因为背后常常是综合素质与机遇的结合,好的结果往往产生于一个阶段,长期需要较快且持续的成长。

但是,如果我们有一些指导性的原则,往往我们能够明白事务的折中点,做出更加合理的设计,以及更加关键的贡献。

ERNIE是百度开创性提出的基于知识增强的持续学习语义理解框架,该框架将大数据预训练与多源丰富知识相结合,通过持续学习技术,不断吸收海量文本数据中词汇、结构、语义等方面的知识,实现模型效果不断进化。ERNIE在情感分析、文本匹配、自然语言推理、词法分析、阅读理解、智能问答等16个公开数据集上全面显著超越世界领先技术,在国际权威的通用语言理解评估基准GLUE上,得分首次突破90分,获得全球第一。在今年3月落下帷幕的全球最大语义评测SemEval 2020上,ERNIE摘得5项世界冠军, 该技术也被全球顶级科技商业杂志《麻省理工科技评论》官方网站报道,相关创新成果也被国际顶级学术会议AAAI、IJCAI收录。ERNIE在工业界得到了大规模应用,如搜索引擎、新闻推荐、广告系统、语音交互、智能客服等。

提醒: ERNIE老版本代码已经迁移至repro分支,欢迎使用我们全新升级的基于动静结合的新版ERNIE套件进行开发。另外,也欢迎上EasyDL体验更丰富的功能(如ERNIE 2.0、ERNIE 2.1、ERNIE领域模型等)。

 下载安装命令 ## CPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle ## GPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

在 ERNIE 2.0 中,新构建的预训练任务类型可以无缝的加入训练框架,持续的进行语义理解学习。通过新增的实体预测、句子因果关系判断、文章句子结构重建等语义任务,ERNIE 2.0 语义理解预训练模型从训练数据中获取了词法、句法、语义等多个维度的自然语言信息,极大地增强了通用语义表示能力。

https://www.xujun.org/.metas/ERNIE_milestone.png

Fedora 工程和指导委员会已经签署了去年 6 月提议的 “取消 Flathub 过滤器” 提案,现在 Flathub 的默认过滤器已关闭,用户可在 Fedora 中安装由 Flathub 提供的所有软件包。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Flathub 是 Fedora 35 中引入的第三方软件管理器,平台上有大约 2000 个应用程序。然而该版本的 Flathub 自带过滤器,通过 GNOME 初始设置启用的 Fedora 只能享受 Flathub 包的部分软件,受许可证影响、专有软件或其他原因而未针对 Fedora 打包的应用则会被 Flathub 默认的白名单给过滤掉,移除过滤器能使 Fedora 用户更容易访问这部分资源。

移除 Flathub 过滤器后,Gnome 安装软件的默认顺序调整为 Fedora Flatpaks → RPMs → Flathub Flatpaks ,意味着只有在系统没有 Fedora Flatpak 或 RPM 时才会默认选择 Flathub Flatpaks。用户也可以手动为每个应用程序选择不同的安装源。GNOME Software 也会显示该应用程序是开源还是专有软件,启用第三方存储库的 UI 时,也会明确指出可能包含专有软件。

在提案详情 | 开发列表讨论 中可以查看更多消息。

Open Source Initiative (OSI) 联合 OpenLogic 发布了一份最新的 2023 年开源状态报告。基于来自全球八个地区、20 多个行业、各种规模组织的开源用户的匿名调查答复,详细介绍了开源软件的使用、采用和挑战。

报告指出,从框架和数据库到 DevOps 工具和 AI/ML/DL 技术等方面,开源软件无处不在。有 80% 的组织在过去一年中增加了对开源软件的使用,开源正在推动全球领先公司各个部门的创新。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

但开源软件仍存在一些安全性、技能缺乏以及后续技术支持方面的问题。有超 40 % 的技术经理认为,开源软件存在安全性和合规性问题;近 40% 的使用开源软件的团队缺乏测试、使用或整合该软件的内部技能。开源软件面临的几大挑战包括:

  • 维护安全策略和合规性:42%。  
  • 缺乏技能、经验或熟练程度:38%。
  • 跟上更新和补丁:37%。
  • 缺乏底层技术支持:36%。
  • 维持 end-of-life 支持:36%。

目前,在“关键业务”中被广泛应用的开源软件包括有 Linux、Apache HTTP、Git、Node.js、WordPress、Tomcat、Jenkins、PHP 和 Nginx。“总体而言,软件已成为许多组织的业务关键,因此开源软件是其数字基础架构的关键部分。更成熟的组织获得了这些关键技术的专业知识,并认识到了通过成为社区的一部分来参与自开源创新的重要性。”

至少有 37% 的组织已经为开源做出了贡献,包括对开源项目或开源组织的贡献(代码或其他活动),相较去年增加了 5%。其中,进行安全扫描活动的贡献者占比最高,达 46%。

展望未来 18 个月,人工智能、机器学习和深度学习是最受关注的技术类型,VR 和 AR 领域也颇受关注。还有云原生开源技术,“在各种类型和规模的组织中都得到了广泛采用”。基于容器的部署正在兴起,旨在支持云原生环境的开源工具也在同步增加。

例如,Kubernetes 的使用率达到 23%,一年内增长了 5%,成为使用第三多的云原生技术。在过去的 12 个月里,几乎所有的云原生技术都在增长。可观察性领域的项目,如 OpenTelemetry、Jaeger 和 Prometheus 采用率都大幅上涨。

编程语言方面,JavaScript 和 Python 继续处于领先地位,但各行业的使用率仅略微增加了一到两个百分点。最流行的三个开源 Java 运行时依然是 OpenJDK、OpenJ9 和 Oracle Java。Oracle Java 的使用率比去年的调查下降了 4 个百分点,而 OpenJDK 和 OpenJ9 保持稳定。

DevOps 开源自动化和配置工具使用率快速增长,前两年的调查显示有近 50% 的受访者表示没有使用过任何此类技术,但现在这一数据已经降为 12%。CI/CD 工具,尤其是云原生 CI 和 CD 工具的采用也在增加。总体而言,Jenkins X、Spinnaker 和 Tekton 的使用量都有所增加。

容器和容器编排技术使用量显着增加,今年达 33% (去年为 18%)。34% 的公司现在使用开源软件开发生命周期 (SDLC) 工具,22% 的公司使用开源内容管理解决方案。容器和容器编排技术,以及软件开发生命周期工具,是投资业最多和最常用的开源技术。

微软在 .NET 平台上提供了对 3 种编程语言的支持 —— C#、F# 和 Visual Basic。近日它公布了针对每种语言的最新支持策略。总的来说,微软依然致力于全面支持上述三种编程语言,重点是 C# 和 F#,他们会优化这两门语言的向后兼容性,并积极推动它们的演化。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

C#

微软表示,将不断发展 C# 以满足开发人员不断变化的需求,并保持最先进编程语言的地位。他们将与负责 .NET 库、开发者工具和工作负载支持的团队合作,积极广泛地进行创新,同时保持语言的“灵魂”。考虑到开发者使用 C# 的领域的多样性,微软将重点关注语言特性和性能改进,使所有或大多数开发者受益,并保持对向后兼容性的高度承诺。他们将继续支持更广泛的 .NET 生态,并扩大其在 C# 未来的作用,同时保持对设计决策的管理。

F#

F# 的知名度可能不如其他两种 .NET 语言。它属于“函数式”语言,微软将其描述为“一种用于编写简洁、健壮和高性能代码的通用编程语言”。与 C# 一样,F# 将支持 .NET 平台改进,并将保持与新 C# 功能的互操作性。微软还指出,它将简化 F# 语言,改进语言、工具和文档,以“降低新开发者和组织的进入门槛”。

此外,提升 F# 的可访问性包括不断努力改写错误消息和简化语言功能。”

Visual Basic (VB)

微软将确保 Visual Basic 仍然是具有稳定设计的简单易用的语言。.NET 核心库(例如 BCL)将支持 VB,并且对 .NET 运行时和库的许多改进也会使 VB 受益。当 C# 或 .NET Runtime 引入需要语言支持的新功能时,VB 通常会采用 consumption-only 方法,并避免使用新语法。

微软不打算将 Visual Basic 扩展到新的工作负载。他们将继续关注 Visual Studio 的体验以及与 C# 的互操作,尤其是在核心 VB 场景(例如 Windows 窗体和库)中。

详情查看 https://learn.microsoft.com/en-us/dotnet/fundamentals/languages

Google 在昨天推出了 ChatGPT 的竞品 Bard,时隔仅仅一天时间,刚向 OpenAI 投资数十亿美的微软就做出了回应。在今天凌晨举行的一场小型发布会上,微软展示了必应(Bing)中由 AI 驱动的新搜索功能,以及内置了相同 AI 技术的新版本 Edge 浏览器。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

微软认为通过使用 AI 技术,全新的 Bing 和 Edge 可以重塑网络搜索和浏览体验。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

必应搜索

首先我们聚焦于 Bing 搜索。根据参会的外媒报道和官方公告,微软展示了 Bing 的两种使用模式,第一种就是大家最熟悉的传统模式,只不过现在 Bing 会将传统的搜索结果与 AI 搜索结果并排显示在一起(如上图)。以微软演示的搜索内容来看,传统的搜索结果仍然是以网站为主体,优先显示最相关的网站;而 AI 搜索结果更加详细,交叉收录了多个网站的信息内容,直接帮助用户查找和总结正在寻找的答案。

另一种模式就跟目前使用 ChatGPT 一样,让用户直接与 Bing 聊天机器人对话,在聊天界面中向 AI 提问。通过这种方式,AI 可以通过上下文获得更多的问题细节和用户的想法,从而优化搜索结果,直到获得最终的完整答案(如下图)。

GPT 3.5 是为 ChatGPT 提供支持的 OpenAI 语言模型,而为 Bing 提供支持的 AI 则是 GPT 3.5 的升级版,微软将其称为 “Prometheus 模型”。除了模型不同,两者最大的不同之处在于,ChatGPT 的数据仅更新至 2021 年,而 Bing 可以检索到最新的资讯。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Edge 浏览器

除了新的 Bing,微软此次还为其 Edge 浏览器推出了两项新的 AI 增强功能 —— 「chat」与「compose」(聊天、撰写),并将这些功能嵌入到 Edge 的侧边栏中。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

“聊天” 允许用户使用 AI 总结归纳他们正在查看的网页或文档,并就其内容提出问题,而 “撰写” 则是让 AI 充当写作助手,根据一些提示,帮助生成从电子邮件到社交媒体帖子等文本内容。

根据微软的演示,演示人员使用 Edge 浏览器访问了 Gap 网站,查询了他们的季度报告和收益,该报告是一份有 15 页的 PDF 文件。然后演示人员通过从浏览器的侧边打开了一个聊天机器人,并要求 AI 提供该页面中的主要信息。下达指令后,AI 就迅速返回了该 PDF 文件的摘要,帮助用户节约大量的时间。

演示人员之后还让 AI 将 Gap 第三季度的财报数据与竞争对手 Lululemon 第三季度的财务数据进行比较,AI 还能迅速将其结果做成表格。

微软今天就已经将新版必应搜索以「有限预览」的形式提供给所有用户使用,只不过目前可以使用的查询数量有限,用户可以访问该链接注册登记,加入候补名单以获得完整访问权限。

摘要:这篇文章属于系统分析类的文章,通过详细的实验分析了离地攻击(Living-Off-The-Land)的威胁性和流行度,包括APT攻击中的利用及示例代码论证。

本文分享自华为云社区《[论文阅读] (21)S&P21 Survivalism: Living-Off-The-Land 经典离地攻击》,作者: eastmount 。

摘要

随着恶意软件检测算法和方法变得越来越复杂(sophisticated),恶意软件作者也采用(adopt)同样复杂的逃避机制(evasion mechansims)来对抗(defeat)它们。

民间证据表明离地攻击技术(Living-Off-The-Land,LotL)是许多恶意软件攻击中最主要的逃避技术之一。这些技术利用(leverage)系统中已经存在的二进制文件来执行(conduct)恶意操作。

基于此,我们首次对Windows系统上使用这些技术的恶意软件进行大规模系统地调查。

在本文中,我们分析了这些本地系统的二进制文件在多个恶意软件数据集上的使用情况,这些数据集共包含31,805,549个样本。我们发现平均流行率(prevalence)为9.41%。实验结果表明,LotL技术被大量的使用,特别是在高级持久性威胁(Advanced Persistent Threat ,APT)恶意软件样本中,离地攻击占比为26.26%,是社区恶意软件的两倍多。

为了验证(illustrate)LotL技术的逃逸潜力,我们在本地沙箱环境(sandboxed environment)中对几个完全打补丁的Windows系统进行了离地攻击技术的测试,其结果表明在10个最流行的反病毒产品(anti-virus)中存在明显的gap。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

一.引言

由于每篇论文的引言都非常重要,会告诉大家为什么有这个工作,以及这个工作做了什么,有什么贡献。因此该部分作者会全文翻译,后续章节则介绍重点内容。

1.什么是离地攻击

恶意软件开发和检测是猫和老鼠的游戏,恶意软件作者不断开发新技术来绕过(bypass)检测系统。像AV杀毒软件(anti-virus)这样的安全产品通过静态和启发式分析(heuristic analysis)技术,以检测、分类和防止恶意软件有效执行。

在过去,许多解决方案严重依赖于基于签名的检测,但不幸的是,由于使用了多态性(polymorphism)和加壳程序(packers),这些方法变得不再那么有效。相反,许多产品开始开发启发式分析解决方案,包括检测恶意行为的算法。这些算法已成为AV引擎的重要组成部分。随着时间的推移,这些算法越来越复杂,因此需要更多创新性的逃避技术。

恶意软件作者和红队经常研究和发现新方法来绕过安全解决方案。虽然它们的潜在目标本质上可能有所不同,但这两种类型的攻击者通常都利用(leverage)最先进(state-of-the-art)的逃避技术来实现目标。从防守者的角度来看,为了及时作出响应,了解这些攻击和研究它们的趋势是至关重要的(crucial)。其中,在红队和恶意软件作者中都流行的规避策略就是使用离地攻击(LotL)技术。

离地攻击(LotL)技术是指使用系统中已经存在或易于安装的二进制文件(如已签名的合法管理工具)来执行后渗透活动(post-exploitation activity)。

  • 通过利用这些工具,攻击者可以实现注册表修改、持久化、网络或系统侦察,或执行其他恶意代码。它们甚至可以用来减少由恶意活动产生的事件日志,而不需要将其他文件下载到本地的系统中。

LotL techniques refer to the use of binaries that are already present on systems or are easy to install (e.g., signed, legitimate administration tools) to conduct post-exploitation activity.

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.APT中的离地攻击

离地攻击并不是隐蔽的技术,它们在互联网上公开记录着。许多开源的攻击安全工具利用了LotL技术,并且经常被攻击者所使用,从合法的红队到业余的网络攻击者,以及有组织的APT团队。

  • PoshSpy[15]:是一个俄罗斯APT29攻击模块,它是第一个被检测到的APT组织使用的LotL技术,特别是在PowerShell和Windows Management中。
    – Dissecting One of APT29’s Fileless WMI and PowerShell Backdoors (POSHSPY)
  • 伊朗威胁组织[1]、APT33、APT34和其他组织也以使用本地Windows二进制文件和其它签名工具而闻名,特别是PowerShell[8]。

表1列出了几个国家背景的APT组织所使用的LotL技术。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

尽管“离地攻击”在信息安全界是一个相对知名的术语,但有时很难找到一个精确的定义。此外,据我们所知,没有任何研究包含了对LotL技术在恶意软件样本中的流行程度的系统分析。

  • Moreover, to the best of our knowledge no research contains a systematic study of LotL techniques’ prevalence in malware samples.

关于LotL技术的文档大多以博客的形式出现,并记录着某些恶意软件家族的在野发现,或者攻击者在远程访问受损系统中所使用技术的描述。

  • 例如,Emotet 和 Trickbot,两个最常见的远程访问木马(Remote Access Trojans,RAT),据称是使用链接的LotL二进制文件来实现持久化。
  • 作为一种对策,微软描述了对抗使用LotL技术商用RAT的基本步骤。高度逃逸的远程访问木马 Astaroth, TA505 组织的一些恶意软件库,Dexphot cryptominer 和 Nodersok 同期使用的多个LotL二进制文件。

3.提出五个关键问题

在本文中,我们分析了LotL现象,即商用恶意软件中与离地攻击二进制文件利用相关的文件。我们首先描述了什么是LotL binary以及它如何被恶意软件利用来实施恶意行为的。

  • Our first step is to describe what a LotL binary is and how it can be leveraged by malicious software to conduct its nefarious actions.

本文的研究重点是以Windows为主导的操作系统下流行且恶意软件最常针对的目标。许多基于离地攻击的AV逃逸行为已被记录下来。因此(As a consequence),安全界很大程度上认为,LotL技术(如代理执行恶意软件)实际上对安全解决方案是有效的。

首先,我们提出了第一个假设以及第一个研究问题:

问题1: Can LotL techniques effectively evade commercial AV?
LotL技术能有效地逃避目前大部分安全厂商的杀毒软件检测吗?

为了回答这个问题,我们评估了一组具有代表性的安全产品,并展示了其中的一些技术,虽然这是攻击者和防御者所熟知的,但仍然是绕过安全解决方案的有效方法,因此对安全行业来说这仍是一个开放的挑战。

事实上,LotL二进制文件经常被系统管理员和高级计算机用户使用来执行(perform)系统管理任务,这使得即使是对于训练有素的分析人员来说,区分(distinguish)合法行为和恶意行为也非常困难。我们负责任地向受影响的供应商披露了我们的发现并进行跟进,因此提高了他们的检测能力。

尽管现有的文档提供了这些技术使用的可靠证据,但仍然不清楚这种现象在恶意软件样本中有多普遍。因此(In this way),我们就提出了第二个研究问题:

问题2:How prevalent is the use of LotL binaries in malware?
在恶意软件中使用LotL二进制文件的情况有多普遍?

在此基础上,我们试图阐明当前威胁情景中的一些趋势,以确定(identify):

问题3:What purposes do malware binaries use LotL techniques for?
恶意软件的二进制文件使用LotL技术的目的是什么?

问题4:Which malware families and types use LotL binaries most prolifically and how does their usage differ?
哪些恶意软件家族和类型使用LotL二进制文件最多,它们的使用情况又有何不同?

此外,我们还调查(investigate)了为什么这些技术难以检测。部分杀毒软件公司参与了我们的披露,即将恶意攻击与系统管理员执行完全合法的管理任务区分开来是困难的。这就给我们带来了另一个问题:

问题5:What are the overlaps and differences in the behavior of legitimate and malicious binaries with respect to the usage of LotL binaries? How would this affect detection by heuristic AV engines?
在使用LotL二进制文件方面,合法和恶意二进制文件的行为有哪些重叠和差异呢?这将如何影响启发式AV引擎的检测呢?

虽然恶意样本和良性样本之间的LotL二进制使用频率(prevalence)有一些明显的差异,但我们也注意到一些类别存在某些相似性,如代理执行(proxied execution)。

最后,我们将注意力集中在高逃逸和高级持续威胁的恶意软件上,我们发现它利用离地攻击技术是商用恶意软件的两倍。在表1中列出了一些使用LotL技术进行攻击的APT组织。

  • Finally, we focus our attention on highly evasive and Advanced Persistent Threat (APT) malware to find out that it leverages these techniques twice as much as commodity malware.

4.贡献(Contribution)

据我们所知,本文提出了迄今为止对商用和APT恶意软件使用LotL技术最大规模的系统分析。本文的核心(core )贡献:

  • 我们通过测试一组最流行的AV引擎来对抗基于LotL技术部署的恶意载荷,以评估LotL技术的可行性,并展示了离地攻击检测的复杂性对行业仍是一个挑战。即使在披露9个月后,这些技术仍没有被发现。
  • 我们对代表现代商用恶意软件的几个数据集进行了大规模的评估,并确定了LotL技术的流行程度,以及在不同恶意软件家族和类型之间的差异。我们还评估了LotL技术由于假阳性风险可能对行业产生的影响。
  • 我们评估了一个APT恶意软件数据集,并将其公开以促进(facilitate)后续的研究,并确定它执行LotL技术的频率是商用恶意软件的两倍。此外,我们还确定了哪些APT组织最多地使用LotL技术。

二.背景和相关工作

我们首先定义LotL二进制文件,并枚举恶意软件使用这些二进制文件的目的。

A.LotL Binaries

近年来,“Living-Off-The-Land binary(LOLbin)”已经成为一个常用词,用来指在网络攻击中广泛使用的二进制文件。历史上,“Living-Off-The-Land”一直被用来表示可以为农业或狩猎提供喂养土地或离地的概念。转换为恶意软件和入侵领域,攻击者可能利用那些已经可以使用的文件(即系统上已经存在或易于安装的)来发起攻击并躲避检测。

在本文中,我们将LotL二进制定义为:

  • 任何具有公认合法用途的二进制文件,在攻击期间利用它直接执行恶意行为,或间接协助一系列恶意行动,从而达到恶意结果。

In this paper, we define a LotL binary as any binary with a recognised legitimate use, that is leveraged during an attack to directly perform a malicious action; or to assist indirectly, in a sequence of actions that have a final malicious outcome.

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

举例:

  • 在Windows系统上默认安装的二进制文件(binaries installed),如 Reg.exe 、Sc.exe 和 Wmic.exe 是最常被恶意软件执行的文件。
  • 大多数默认安装的二进制文件都是由微软认证码签名的。认证码签名证明二进制文件没有在编译中被篡改或修改,这些二进制文件甚至可能被列为白名单。利用可信的LotL二进制文件的恶意软件可能因此避开杀毒软件。在Windows系统上使用系统二进制文件可以作为恶意软件操作的一部分,更重要的是,许多LotL技术使用系统二进制文件来实现这些二进制文件的目的。
  • 此外,可以使用外部签名二进制文件(external signed binaries),如 PsExec.exe 或其他系统内部二进制文件。虽然它们使用频率不高,但本文的分析也囊括了这些文件。如APT组织在 SoftCell 和 Havex 中都使用 PsExec.exe 来秘密执行远程命令,从而实现网络中的横向移动。
  • 某些罕见情况,脆弱的(已签名)驱动程序被用来升级系统上的权限。这是 RobbinHood 勒索软件和各种 APT wiper 恶意软件样本所使用的一种技术,针对 Saudi Arabian 系统,包括 Dustman 、Shamoon 和 Zerocleare。

可追溯性(Traceability)

  • 某些LotL二进制文件可能会比其他文件留下更多的系统日志,安全工具或取证分析人员可以利用这些日志来检测恶意操作。例如,可以将Powershell配置为具有全面的日志记录。
  • 微软甚至建议阻止在系统上执行一些本机的二进制文件,除非有充分的理由。

B.Scope of our Study

在本文中,我们关注的是Windows恶意软件执行系统二进制文件的目的。这些目的通常包括沿着 kill chain 的进展或逃避AV的检测。所有这些技术都被部署在系统的用户空间中。

hollowing 和 injection(注入) 不在我们的研究范围内,尽管这是无文件恶意软件部署的常见技术。因为根据我们早期的定义,它们不是LotL技术。

C.Related Work

离地攻击相关工作较少,并且都非常经典,因此下面罗列了详细的相关研究,仅供自己后续深入,也希望对您有所帮助。

LotL恶意软件及其别名,“advanced volatile threat”或“无文件”恶意软件在当前的学术文献中很少被提及。这主要受限于介绍分析少或描述为一个新兴的高逃逸恶意软件变体。

  • Li等[31]对恶意PowerShell脚本进行了分析,其中有一个小节专门描述了LotL攻击和无文件攻击作为近年来网络攻击的趋势。(作者第17篇博客详细介绍过PS经典
  • Wang等[72]最近发表的一篇关于数据来源分析的论文指出,Living-Off-The-Land 是一种新兴的、突出的逃避型恶意软件子类(evasive malware subtype)。(经典的You Are What You Do后续即将分享
  • 先前的工作[64]进行了介绍性分析,然而LotL恶意软件还没有受到详细的学术分析。(An emerging threat Fileless malware: a survey and research challenges)
  • 赛门铁克[73,66]和思科Talos的[65]白皮书介绍了这个主题,并对多个数据集的流行性进行了分析。目前,没有论文对包含多个使用LotL技术的Windows恶意软件数据集进行大规模地系统分析。(经典
     https://www.symantec.com/content/dam/symantec/docs/security-center/white-papers/istr-living-off-the-land-and-fileless-attack-techniques-en.pdf
     https://www.symantec.com/content/dam/symantec/docs/white-papers/living-off-the-land-turning-your-infrastructure-against-you-en.pdf
     https://blog.talosintelligence.com/2019/11/hunting-for-lolbins.html
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在一些论文中提到了LotL技术,强调了高隐蔽(stealthiness)和APT恶意软件曾使用。

  • 在一篇关于恶意软件分析工具Yara的论文中,Cohen[9]将LotL描述 “ LotL as a trend that has been recently observed in the tactics used by elite threat actors”,我们的分析结果进一步证实了该说法。
  • Hassan等[21]的研究表明,APT恶意软件使用LotL攻击策略来实现持续攻击并分析了两个活动,他们的工作还利用了MITRE ATT&CK框架[45],通过MITRE定义了一个描述和分类知名攻击的分类方法。许多LotL技术在MITRE ATT&CK框架内被索引。Mitre公司及其常见CVE漏洞是安全领域的既定权威,他们囊括并描述许多LotL技术,这样表明离地攻击是一个值得深入分析的课题。
    – W. U. Hassan, A. Bates, and D. Marino, “Tactical Provenance Analysis for Endpoint Detection and Response Systems,” IEEE Symposium on Security and Privacy, 2020.

强烈推荐一个包含LotL二进制和ATT&CK功能映射的资源

  • https://github.com/LOLBAS-Project/LOLBAS
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

与我们研究相关的是对基于脚本的恶意软件分析和去混淆。使用LotL技术的恶意软件经常使用恶意脚本作为有效负载。(下列论文在作者第16篇PowerShell总结博客中详细介绍过

  • Ugarte等[67]通过识别可疑行为模式,测试了经 Powershell.exe 二进制调用的恶意脚本。
  • Rubin等[61]将机器学习应用于检测PowerShell恶意软件(微软团队)。
  • Curtsinger[11]等人提出了恶意Javascript攻击的检测机制——ZOZZLE。

虽然这些论文提出了有效的检测方法,但是他们都是为狭隘的恶意载荷(payload)所用,他们没有分析更广泛的恶意软件生态系统和这些有效载荷是如何被LotL二进制文件触发的。

三.MOTIVATION: 杀毒软件产品 vs 离地攻击技术

安全研究人员已经记录了许多使用LotL技术成功躲避安全产品的案例。在许多情况下,这些LotL二进制文件被用来代理恶意载荷的执行,使其在一个合法的进程上下文中执行,或者作为一个合法系统进程的子进程生成一个新进程。在某些情况下,这些有效载荷作为LotL二进制调用的副作用被执行,而在其他情况下,它只是其主要记录行为的结果。此外,许多杀毒产品未能正确检测到这些技术。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

为了回答第一个问题,我们首先分析了当前AV产品是否将LotL技术作为恶意行为的指标。

为此,我们首先选择了10个具有代表性的AV产品(详见附录C),并利用常见基于LotL的代理执行技术来实施反弹Shell的模拟攻击。此外,本研究的目的不是测试任何特定AV产品的检测能力或将它们相互比较,而是确定是否存在普遍的检测差距。

  • 实验在联网的Windows 10虚拟机执行,并将最新的本地AV产品连接到它们的云组件。
  • 利用一个反弹Shell来评估AV系统在部署LotL技术的恶意软件中有多脆弱。本文认为能够允许远程执行命令的reverse shell是成功执行代码的证明,这与许多远程访问木马(RAT)功能相同。
  • 通过从不同LotL二进制文件中运行这个反弹shell来进行实验,以测试AV产品是否检测到离地攻击技术是恶意的。
  • 我们在必要时混淆了反弹shell的有效载荷,并使用各种有效载荷类型来测试AV检测传递机制本身的能力,而不是通过静态签名传递的特定有效载荷(详见附录D)。

实验结果如表2所示:

  • 可以发现大部分的AV引擎允许我们建立一个反弹Shell并执行命令,它们并没有检测出利用LotL技术的恶意软件,60个中只检测出4个。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Responsible Disclosure and Response.

此后,我们向相关的AV供应商发布了一份文件,包含我们检查的结果并协助补救。9个月后,我们在Windows 10机器上重复了类似的测试,这允许我们测试AV供应商是否在他们的产品中包含了新的启发式规则来检测LotL二进制的使用。其结果如下:

  • 可以发现在60个相同的有效载荷中检测到了25个
  • 在检测到的反弹shell测试中,我们修改了载荷(利用混淆或运行不同的载荷),同时为LotL二进制文件保持了完全相同的命令行参数,通过利用这些混淆和修改的有效载荷,我们成功地在这25个被拦截的实例中的19个执行了一个反向shell。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

实验结果表明,LotL技术仍然是杀毒软件供应商面临的一个重大挑战。合法用户通常以不可预知的方式使用这些工具,而安全公司很难在没有误报的情况下部署有效的检测策略。

接下来将展示这些技术如何在商用恶意软件中是普遍存在的,以及离地攻击是不应该被安全社区忽视的问题。

四.离地攻击流行性评估

在本节中,我们测量了恶意软件中LotL技术的流行程度,并试图回答所提出的研究问题。

A.Dataset Composition

评估工作是在9个独立的子数据集上进行的。我们总共收集了31,805,549个样本,其中我们从VirusTotal(VT)中获得了16,048,202份行为报告。

  • To be as comprehensive as possible, we obtained public and private datasets from different sources.
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Public Datasets

  • 公共恶意软件数据集,包括商用恶意软件、VirusShare语料库的二进制文件、窗口恶意PE文件、佐治亚理工学院发布的可执行文件、VX-Mumbal和MalShare共享的样本(两个重点的共有数据集)。
    – https://impactcybertrust.org/dataset{ }view?idDataset=1143
     https://vx-underground.org/samples.html
     https://malshare.com

VirusTotal Balanced Dataset

  • 从VT中收集了237,288个hash值,利用 AVClass 预处理代码和打标签(家族分类),并平衡数据集中每个族。

APT Malware

  • 我们根据一种类似于数据集论文dAPTaset[59]的方法收集了一个APT恶意软件的数据集。我们处理了HTML页面和pdf文件(),并提取了这些文件中包含的所有恶意软件的hash值。
     https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-rezaeirad.pdf
     https://github.com/aptnotes/data

Yara Rule Match Malware

  • 部署3个Yara规则来检测LotL二进制文件,并使用Livehunte来识别上传到VT的新的恶意软件hash,并使用LotL技术匹配恶意软件的行为特征。

B.Analysis Pipeline

当收集了由Windows PE二进制文件组成的不同数据集,我们就分析样本的行为。包括三个阶段:

  • data collection
  • data augmentation
  • data analysis

First Seen:首次发现病毒样本的时间戳
AVClass Family:某恶意软件样本所属家族
Behavioural Report:恶意行为报告,由特定恶意软件样本执行的进程和Shell命令的列表

C.LotL Technique Identification

数据准备就绪,那么如何识别是否使用了LotL技术呢?

我们使用模式匹配来识别恶意软件执行过程中对LotL二进制文件调用的情况,从而处理所有收集到的行为报告(behavioural reports)。行为报告包括两个指标:

  • Shell Commands(Shell命令)
    恶意二进制文件在主机操作系统中执行的Shell命令,Shell命令日志可以通过引用系统二进制文件的绝对路径来显示它的执行情况。同时,Windows的命令提示符还包括许多别名,例如Reg.exe的reg。
  • Processes(进程)
    进程日志明确由恶意软件样本执行的系统二进制文件。执行的参数也包含在行为报告中的进程日志中。

在我们的分析中,如果一个样本的行为报告包含至少一个LotL二进制文件的执行,那么它使用了LotL技术。我们记录了每一个LotL的执行及其参数细节,并将它们插入到数据库中。然后,我们分析了这些恶意软件样本的参数,以确定每个数据集中最常见的参数类型和执行目的。

具体而言,我们确定了这两种独立类型的二进制文件:

  • Default System Binaries
  • Installed Signed Binaries

Pattern Matching Refinement
模式匹配方法在不断改进,直到所有识别的LotL命令被正确分类和映射到执行目的,并进行了数据清洗处理。

  • 不带参数的二进制执行移除
  • 沙箱产物删除(如Explorer.exe和sha256),Web访问不处理
  • 删除Verclsid.exe的实例

D.Parameter Analysis to Identify Execution Purpose

为了确定LotL技术的执行目的,我们观察了恶意软件样本提供的参数。

图1说明了四个进程执行的映射。该映射通过识别单独的执行目的来在所有数据集上实施,例如执行Net.exe时使用stop参数表示任务停止。在将单个命令映射到执行目的之后,我们将为该二进制文件选择所有匹配的执行。我们在所有系统二进制执行中重复该步骤,直到每次执行被分类为属于特定的执行目的或被错误分类。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

按照这种方法,我们按目的将参数分为9个独立的类别。

首先是三种与执行有关的类型:

  • Proxied Execution
    代理执行,如Mshta.exe执行.hta文件,Rundll32.exe执行.dll文件
  • Persistence
    如果恶意代码配置或修改系统以在未来某个时间点执行命令或存储的作业,那么它就实现了持久性,比如Sc.exe带有创建参数的Bitsadmin.exe,或带有日期时间参数的Schtasks.exe/At.exe
  • Delayed Execution
    延迟执行,比如 Ping.exe执行-n

接着是三类与底层系统组件的修改有关。恶意软件通常从事这种行为,以便在机器上对目标进行进一步的传播或行动。

  • Firewall Modification
    防火墙修改,如Netsh.exe
  • Registry Modification
    注册表修改,如Reg.exe
  • Permissions Modification
    权限修改,如Cacls.exe修改文件权限

最后是与执行或系统修改无关的三类。

  • File Opening
    打开文件,如Explorer.exe
  • Reconnaissance
    侦察,触发本地或远程配置的横向移动,如Net.exe
  • Task Stopping
    使用LotL二进制文件秘密停止另一个进程或服务,如Taskkill.exe
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

五.评估结果

A.商用恶意软件中LotL技术的流行性(Prevalence)

Relative Prevalence Between Datasets.

图2显示了在每个数据集中使用LotL技术的恶意软件样本的百分比。

  • 如果省略Ember良性数据集和APT恶意软件数据集(最小值和最大值),我们可以观察到,5.42%到12.72%的商用恶意软件样本至少使用了一次LotL技术。
  • 在VT平衡数据集中,我们可以观察到9.6%的样本利用了这种类型的技术。
  • APT数据集使用LotL技术的频率明显高于商用恶意软件。26.26%的APT数据集使用了LotL技术,是类似的商品恶意软件数据集的两倍多。

这些数字表明,LotL技术是一个普遍的现象,尤其是APT攻击中。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Most Frequently Used LotL Binaries

表5显示了商用恶意软件数据集中最常执行的LotL二进制文件。

  • VT数据集中最常用的二进制文件是Reg.exe、Nslookup.exe、Regasm.exe、Runas.exe、Schtasks.exe和Sc.exe。
  • 其中一些二进制文件用于系统管理任务,如编辑注册表或创建计划任务;其他的则用于更改或提升特权,或启用网络活动。

值得注意的是,某些二进制文件在不同的数据集之间显示了不同的分布。这意味着尽管LotL技术是在恶意软件编写中被广泛使用,但它们在恶意软件家族或恶意软件类型中以异构的方式使用。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Parameters and Execution Purpose

我们还通过解析最常用的LotL二进制文件的参数来确定出现它们的执行目的。图3显示了执行目的的结果分布。

  • 最常见的目的是代理执行、侦察、任务停止和修改注册表。
  • 我们还可以观察到,数据集之间有显著的变化,如预期的结果表5所示。这些结果表明,恶意软件使用LotL二进制文件不仅秘密执行其他代码,也通过注册表修改修改底层操作系统,使横向移动通过侦察,或避免其他软件运行在系统中。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Malware Families

我们确定了一些利用LotL技术的常用恶意软件家族,恶意软件采用的LotL二进制代码非常少,我们将这种分类限制在包含至少100个样本的家庭。图4显示了AVClass报告的家族数量,其样本使用LotL技术技术的特定百分比。

  • 大量的家族没有使用LotL二进制文件,而少数家族呈现出这些技术的高流行率。这意味着,虽然总体上大量采用了LotL技术,但这些技术的使用主要集中在有限数量的家族中。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

B.Comparison of Benign and Malicious Samples

我们已经观察到,LotL技术在商用恶意软件和APT活动中都是一种普遍的现象,尽管在恶意软件类型或家族之间可能存在一些差异,但很明显,安全行业不应该忽视这种威胁。考虑到这一点,我们提出了另一个问题:

  • 为什么一些安全产品难以检测这些技术?

在本文的开头,我们确认了许多AV产品不能有效地检测这些二进制文件的使用,并且对我们披露的信息响应后,其检测机制仍然非常容易出现假阳性。在本节中,我们将比较合法软件中使用LotL二进制文件的情况。

表VI显示了良性数据集中最常执行的二进制文件。

  • Regsvr32.exe、Sc.exe和Rundll32.exe是最常用的执行二进制文件之一,所有这些文件都用于执行代码。我们可以注意到,恶意软件(表V)和良性软件(表VI)最常执行的二进制文件有显著差异。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图5显示了利用LotL技术按执行目的进行分组的示例。

  • 我们观察到,虽然某些执行目的在恶意二进制文件中比在良性二进制文件中更为普遍(如侦察、持久性和注册表修改),但对其他二进制文件则有相反的趋势。例如,在恶意软件和良性软件中,最常见的目的是代理执行,这一发现与我们在第三节中的观察结果相关联。
  • 结果表明,这些行为模式对启发式AV算法的创造者提出了重大挑战。这也反映在一些供应商对我们负责披露的反应上,即假阳性风险明显很高。
  • 这一发现还同时说明,并非所有的LotL二进制文件在良性软件和恶意软件中都同样普遍,因此AV供应商仍然有机会创建启发式规则来识别在良性软件中不那么流行的技术类型。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

C.Prevalence of LotL techniques in APT Malware

我们观察到LotL技术在APT恶意软件中明显比商品恶意软件更频繁(见图2)。接下来我们专注于APT恶意软件的评估。

首先,我们展示了使用LotL二进制文件比例最高的特定APT活动,并根据威胁情报报告对它们进行分组。我们还列举了APT恶意软件最常利用的LotL二进制文件。表7列出了我们在APT数据集中观察到的最常见的LotL二进制文件。

  • APT恶意软件使用了许多与商用恶意软件相同的二进制文件,其中Ping.exe是最常见的一个。
  • 我们观察到APT恶意软件主要使用LotL技术来延迟和代理执行,以及侦察。这可能在一定程度上反映了APT恶意软件旨在实现隐蔽的横向移动和泄漏数据。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

表8显示了一些大量使用LotL技术的APT活动,这些活动来源于行为数据的威胁情报报告。值得注意的是,一些APT组有多个活动和样本,如APT28和Keyboy。

  • 这表明APT组织在多个活动中使用了LotL技术。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

六.案例分析

在本节中,我们将调查并描述来自数据集中的两个勒索软件(ransomware)家族:

(1) Gandcrab

我们在本地沙箱环境中执行了Gandcrab勒索软件样本,并记录了所执行的命令。其使用的LotL二进制文件如下。我们使用Nslookup.exe二进制文件观察了家族中的其他样本,传递一个参数“gandcrab.bit”或一个类似的域。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

C: WindowsSystem32cmd.exe /c vssadmin delete shadows /all /quiet

C: WindowsSystem32cmd.exe /c wmic shadowcopy delete

(2) Cerber

除了通过LotL二进制文件进行代理执行外,我们还观察到了Cerber正在使用的其他规避技术,如进程注入。与其他勒索软件家族不同,Cerber不删除副本。然而,我们注意到了一个特别复杂的代理执行链,即Wscript.exe和Rundll32.exe依次执行一个恶意的 “.vbs” 和 “.dll” 文件。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们还观察到,Cerber通过Ping.exe延迟执行,并修改注册表以实现持久化。它将一个恶意的 “.vbs” 文件添加到下面的注册表项中,这意味着每次用户登录时都会运行这个恶意脚本。

  • HKEY_CURRENT_USERSoftwareMicrosoftWindows
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们还注意到一些Cerber样本调用Mshta.exe来打开hta文件。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

C:WindowsSystem32WScript.exe C:Users admin enYXval36C38oDr5.vbs

C:WindowsSystem32Rundll32.exe 8ivq.dll arzy949

C:WindowsSystem32cmd.exe /c ping 127.0.0.1 && reg add HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRunOnce /v enYXval36C /t REG SZ /d C:enYXval36CenYXval36CenYXval36C.vbs /f

C: WindowsSystem32mshta.exe ransom.hta

我们还描述了两个APT恶意软件组织:

  • Turla
  • GreyEnergy

APT组织Turla显示了LotL技术的利用演变,而GreyEnergy参与了对乌克兰电网的高度破坏性攻击。我们手动分析了这些样本中的LotL二进制文件。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

C: WindowsSysWOW64Rundll32.exe {64F97CDC…FAB40CA}.db #1 #1}

C: WindowsSystem32cmd.exe /c ( ping localhost >> nul & del $path grey3.exe >> nul )

图6显示了APT组织Turla越来越多地采用LotL技术,比如两个连续的模块化高逃逸木马,即Cobra(2014)和Mosgodo(2018)。

  • 掩盖恶意dll,更换后缀通过rundll32执行
  • 删除自身移除取证
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

七.要点和讨论

我们的结果证实了LotL技术不是一个不可忽视的现象。虽然有几篇技术文章涵盖了这个主题,但我们的系统评估会进一步促进对商用恶意软件采用这种技术的理解。在本文中,我们检查了几个不同的恶意软件数据集,并进行了一个AV评估实验,其中我们确认了几种已记录的LotL技术的低检测率。根据这些结果,我们可以得出以下结论:

  • 我们测试的几乎每一个流行的AV产品都难以检测到LotL二进制文件的恶意使用。即使很负责地向每个供应商披露这些问题后,也只有一小部分供应商成功优化了检测机制。其中一些供应商针对我们的特定恶意载荷实现了检测机制,但没有实现交付机制本身。其他报告说,由于存在禁止性的假阳性风险,实施此类对策具有挑战性。
  • 为了纠正这一检测差距,我们与AV供应商合作,以提高其检测能力。例如,卡巴斯基实现了由我们披露所产生的检测,如 Trojan.Win32.Lolbas.btad.exec 和 TrojanSpy.Win32.Agent.ftps。我们还发布了Yara规则来帮助检测LotL技术。此外,我们的研究表明,良性样本和恶意样本之间的执行目的存在差异,为检测算法的发展提供了一个方向。事实上,最近的论文[71, 21]探索了这条有前途的研究路线,以克服现有安全产品的局限性。
  • 在一些描述中,LotL技术专门指可以实现AV逃逸方法的子集。然而在本文中,我们采用了更广泛的范围,并观察到在AV平衡数据集中,9.6%的恶意软件使用本地系统二进制来执行恶意行为。
  • 关于执行目的,我们观察到LotL二进制文件不仅用于代理执行或逃逸,而且还用于实现常见的恶意例程,如延迟执行、修改系统配置、持久化或停止安全服务。
  • 据AVClass工具报道,不同家族中LotL技术的流行率存在很大的差异。然而我们可以观察到,大多数家族的流行率较低,而少数家族使用这些技术的流行率要高得多。这意味着这些技术足够普遍,可以被某些恶意软件的作者所采用,但并不是在恶意软件中实现恶意功能的唯一或最普遍的方式。
  • 合法软件使用的LotL二进制文件要少于恶意软件,尽管这些二进制文件用于不同的目的,但其流行程度足以使恶意使用的准确检测成为安全供应商面临的挑战。相反,在APT攻击中利用LotL二进制文件是普通商用恶意软件的两倍。

鉴于这些证据,我们可以得出结论,LotL技术在当前最先进的恶意软件中得到了重要的应用,从检测的角度来看,它们代表了安全行业的一个挑战。通过这篇论文,我们试图阐明这一现象,并提高研究界对这个开放问题的认识。

  • LOLBAS Project Contributions.

八.局限性和未来工作

Intended or Unexpected Functionality.
测量结果没有区分二进制文件的标准功能和利用副作用来实现某些结果的非标准使用。例如一个预期使用
Netsh.exe修改防火墙规则,而意外使用Netsh.exe运行.dll。

局限性:

  • Anti-VM Malware.
    由于数据来自于云中托管的动态分析沙箱,恶意软件使用的反虚拟机规避技术可能会影响数据质量。我们通过排除在沙箱中执行最少或执行过程中崩溃的恶意软件样本来减轻这种情况。这可能会影响数据质量,因为使用反虚拟机技术的规避恶意软件并不能显示其实际行为。因此,我们可能低估了使用LotL二进制文件样本的数量。然而,我们的数据是这种技术流行程度的一个下限,并证明了这是一个不应被忽视的重要现象。
  • Human Operators.
    许多使用LotL技术的攻击者都是执行远程Shell、攻击性安全工具、PowerShell、VisualBasic或批处理脚本的人员。虽然有类似案例的民间证据,但很难像我们那样对一个有代表性的数据集进行测量研究。相反,我们缩小了论文的范围,并专注于恶意软件对LotL二进制文件的使用。我们展示了这种现象是不可忽视的,恶意软件作者也在他们的二进制文件中利用这些技术,而不仅仅是在开发后的脚本中。

后续工作:

  • Linux LotL.
    未来的研究方向是探索这些技术在Linux系统上的使用(名为GTFObins[19])。与Windows上的LotL技术类似,这些二进制文件可以用于实现恶意功能。虽然Linux恶意软件没有Windows那么多,但由于运行轻量级Linux系统的物联网僵尸网络的兴起,它是一个值得分析的主题。
  • Detection.
    该领域的另一个未来研究方向是检测技术的部署,这些技术试图准确地捕获LotL技术的识别使用模式,如端点检测和响应(Endpoint Detection and Response,EDR)系统。未来的研究应该利用最近关于进程执行链的数据来源分析的工作[71,21],以实现对合法进程关系的建模和识别可疑的行为模式。

九.个人感受

写到这里,这篇文章就分享结束了,再次感谢论文作者及引文的老师们。接下来是作者的感受,由于是在线论文读书笔记,仅代表个人观点,写得不好的地方,还请各位老师和博友批评指正,感恩遇见,读博路漫漫,一起加油~

个人总结:

这篇文章属于系统分析类的文章,通过详细的实验分析了离地攻击(Living-Off-The-Land)的威胁性和流行度,包括APT攻击中的利用及示例代码论证。这类评估类的文章感觉比较难写,反正我很难写出来,但非常值得学习,感谢作者们的分享。同时,论文的研究背景、五个问题抛出、再到数据集采集、实验论证、回答问题、图表比较以及写作都非常棒,工作量是非常大,譬如常用10种AV引擎的评估以及九个月后的再次验证实验,就可以看到其工作量及贡献(LotL技术很难被发现)。

具体贡献如下:

  • 这篇论文应该算是LotL系统分析的开山之作,本文提出了迄今为止对商用和APT恶意软件使用LotL技术最大规模的系统分析。在这之后可能会吸引更多的安全从业者将目光投向这个领域。
  • 本文通过最流行的AV引擎进行评估,以验证LotL技术部署在恶意载荷中的可行性及流行度,并展示了离地攻击检测的复杂性对行业仍是一个挑战。即使在披露9个月后,这些技术仍没有被发现。
  • 我们对代表现代商用恶意软件的几个数据集进行了大规模的评估,并确定了LotL技术的流行程度,以及在不同恶意软件家族和类型之间的差异。我们还评估了LotL技术由于假阳性风险可能对行业产生的影响。
  • 我们评估了一个APT恶意软件数据集,并将其公开以促进(facilitate)后续的研究,并确定它执行LotL技术的频率是商用恶意软件的两倍。此外,我们还确定了哪些APT组织最多地使用LotL技术

同时,我们回过头来再看看作者提出的五个问题,以及它是如何进行实证分析的。

  • 问题1: LotL技术能有效地逃避目前大部分安全厂商的杀毒软件检测吗?
    通过10种最流行AV引擎检测六种类型LotL样本论证(表2和表3),目前安全厂商的杀毒软件很难检测,即使在披露9个月后,这些技术仍没有被发现。
  • 问题2:在恶意软件中使用LotL二进制文件的情况有多普遍?
    通过公开数据集和私有数据集以及APT数据集论证了LotL技术是一个普遍的线性,并且APT数据集使用LotL技术的频率明显高于商用恶意软件(图2)。26.26%的APT数据集使用了LotL技术,是类似的商品恶意软件数据集的两倍多。
  • 问题3:恶意软件的二进制文件使用LotL技术的目的是什么?
    通过解析最常用的LotL二进制文件的参数来确定出现它们的执行目的。图3显示了执行目的的结果分布,最常见的目的是代理执行、侦察、任务停止和修改注册表。此外,表5显示了商用恶意软件数据集中最常执行的LotL二进制文件,VT数据集中最常用的二进制文件是Reg.exe、Nslookup.exe、Regasm.exe、Runas.exe、Schtasks.exe和Sc.exe。
  • 问题4:哪些恶意软件家族和类型使用LotL二进制文件最多,它们的使用情况又有何不同?
    通过确定一些利用LotL技术的常用恶意软件家族,图4显示了AVClass报告的家族数量,其样本使用LotL技术技术的特定百分比。研究发现,大量的家族没有使用LotL二进制文件,而少数家族呈现出这些技术的高流行率。这意味着,虽然总体上大量采用了LotL技术,但这些技术的使用主要集中在有限数量的家族中。
  • 问题5:在使用LotL二进制文件方面,合法和恶意二进制文件的行为有哪些重叠和差异呢?这将如何影响启发式AV引擎的检测呢?
    某些执行目的在恶意二进制文件中比在良性二进制文件中更为普遍(如侦察、持久性和注册表修改),但对其他二进制文件则有相反的趋势,这些行为模式对启发式AV算法的创造者提出了重大挑战。同时,并非所有的LotL二进制文件在良性软件和恶意软件中都同样普遍,因此AV供应商仍然有机会创建启发式规则来识别在良性软件中不那么流行的技术类型。

此外,本文还分析了APT数据集中观察到的最常见的LotL二进制文件以及真实的APT案例。我们观察到APT恶意软件主要使用LotL技术来延迟和代理执行,以及侦察。这可能在一定程度上反映了APT恶意软件旨在实现隐蔽的横向移动和泄漏数据。

 

关注,第一时间了解华为云新鲜技术~

本文内容整理自 博学谷狂野架构师

file

​ CAP 定理又被称作布鲁尔定理,是加州大学的计算机科学家布鲁尔在 2000 年提出的一个猜想。2002 年,麻省理工学院的赛斯·吉尔伯特和南希·林奇发表了布鲁尔猜想的证明,使之成为分布式计算领域公认的一个定理。

​ 布鲁尔在提出CAP猜想时并没有具体定义 Consistency、Availability、Partition Tolerance 这3个词的含义,不同资料的具体定义也有差别,为了更好地解释,下面选择Robert Greiner的文章《CAP Theorem》作为参考基础。

CAP理论的定义

在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(PartitionTolerance)三者中的两个,另外一个必须被牺牲。

Consistency、Availability、Partition Tolerance具体解释如下:

C – Consistency 一致性

A read is guaranteed to return the most recent write for a given client. 对某个指定的客户端来说,读操作保证能够返回最新的写操作结果。

​ 这里并不是强调同一时刻拥有相同的数据,对于系统执行事务来说,在事务执行过程中,系统其实处于一个不一致的状态,不同的节点的数据并不完全一致。

​ 一致性强调客户端读操作能够获取最新的写操作结果,是因为事务在执行过程中,客户端是无法读取到未提交的数据的,只有等到事务提交后,客户端才能读取到事务写入的数据,而如果事务失败则会进行回滚,客户端也不会读取到事务中间写入的数据。

A – Availability 可用性

A non-failing node will return a reasonable response within a reasonable amount of time (no error or timeout). 非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。

​ 这里强调的是合理的响应,不能超时,不能出错。注意并没有说“正确”的结果,例如,应该返回 100 但实际上返回了 90,肯定是不正确的结果,但可以是一个合理的结果。

P – Partition Tolerance 分区容忍性

The system will continue to function when network partitions occur. 当出现网络分区后,系统能够继续“履行职责”。

这里网络分区是指: 一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障(节点间网络连接断开、节点宕机),使得有些节点之间不连通了,整个网络就分成了几块区域,数据就散布在了这些不连通的区域中。

一致性、可用性、分区容忍性的选择

​ 虽然 CAP 理论定义是三个要素中只能取两个,但放到分布式环境下来思考,我们会发现必须选择 P(分区容忍)要素,因为网络本身无法做到 100% 可靠,有可能出故障,所以分区是一个必然的现象。

​ 如果我们选择了 CA(一致性 + 可用性) 而放弃了 P(分区容忍性),那么当发生分区现象时,为了保证 C(一致性),系统需要禁止写入,当有写入请求时,系统返回 error(例如,当前系统不允许写入),这又和 A(可用性) 冲突了,因为 A(可用性)要求返回 no error 和 no timeout。

因此,分布式系统理论上不可能选择 CA (一致性 + 可用性)架构,只能选择 CP(一致性 + 分区容忍性) 或者 AP (可用性 + 分区容忍性)架构,在一致性和可用性做折中选择

CP – Consistency + Partition Tolerance (一致性 + 分区容忍性)

file

​ 如上图所示,因为Node1节点和Node2节点连接中断导致分区现象,Node1节点的数据已经更新到y,但是Node1 和 Node2 之间的复制通道中断,数据 y 无法同步到 Node2,Node2 节点上的数据还是旧数据x。

​ 这时客户端C 访问 Node2 时,Node2 需要返回 Error,提示客户端 “系统现在发生了错误”,这种处理方式违 背了可用性(Availability)的要求,因此 CAP 三者只能满足 CP。

AP – Availability + Partition Tolerance (可用性 + 分区容忍性)

file

​ 同样是Node2 节点上的数据还是旧数据x,这时客户端C 访问 Node2 时,Node2 将当前自己拥有的数据 x 返回给客户端 了,而实际上当前最新的数据已经是 y 了,这就不满足一致性(Consistency)的要求了,因此 CAP 三者只能满足 AP。

注意:这里 Node2 节点返回 x,虽然不是一个“正确”的结果,但是一个“合理”的结果,因为 x 是旧的数据,并不是一个错乱的值,只是不是最新的数据。

​ 值得补充的是,CAP理论告诉我们分布式系统只能选择AP或者CP,但实际上并不是说整个系统只能选择AP或者CP,在 CAP 理论落地实践时,我们需要将系统内的数据按照不同的应用场景和要求进行分类,每类数据选择不同的策略(CP 还是 AP),而不是直接限定整个系统所有数据都是同一策略。

​ 另外,只能选择CP或者AP是指系统发生分区现象时无法同时保证C(一致性)和A(可用性),但不是意味着什么都不做,当分区故障解决后,系统还是要保持保证CA。

CAP理论的延伸——BASE理论

file

​ BASE 是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency),核心思想是即使无法做到强一致性(CAP 的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性。

BA – Basically Available 基本可用

分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。

​ 这里的关键词是“部分”和“核心”,实际实践上,哪些是核心需要根据具体业务来权衡。例如登录功能相对注册功能更加核心,注册不了最多影响流失一部分用户,如果用户已经注册但无法登录,那就意味用户无法使用系统,造成的影响范围更大。

S – Soft State 软状态

​ 允许系统存在中间状态,而该中间状态不会影响系统整体可用性。这里的中间状态就是 CAP 理论中的数据不一致。

E – Eventual Consistency 最终一致性

系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。

​ 这里的关键词是“一定时间” 和 “最终”,“一定时间”和数据的特性是强关联的,不同业务不同数据能够容忍的不一致时间是不同的。例如支付类业务是要求秒级别内达到一致,因为用户时时关注;用户发的最新微博,可以容忍30分钟内达到一致的状态,因为用户短时间看不到明星发的微博是无感知的。而“最终”的含义就是不管多长时间,最终还是要达到一致性的状态。

BASE 理论本质上是对 CAP 的延伸和补充,更具体地说,是对 CAP 中 AP 方案的一个补充:

  • CP 理论是忽略延时的,而实际应用中延时是无法避免的。 这一点就意味着完美的 CP 场景是不存在的,即使是几毫秒的数据复制延迟,在这几毫秒时间间隔内,系统是不符合 CP 要求的。因此 CAP 中的 CP 方案,实际上也是实现了最终一致性,只是“一定时间”是指几毫秒而已。

  • AP 方案中牺牲一致性只是指发生分区故障期间,而不是永远放弃一致性。 这一点其实就是 BASE 理论延伸的地方,分区期间牺牲一致性,但分区故障恢复后,系统应该达到最终一致性。

数据一致性模型

前面介绍的BASE模型提过“强一致性”和“最终一致性”,下面对这些一致性模型展开介绍。

​ 分布式系统通过复制数据来提高系统的可靠性和容错性,并且将数据的不同的副本存放在不同的机器上,由于维护数据副本的一致性代价很高,因此许多系统采用弱一致性来提高性能,下面介绍常见的一致性模型:

强一致性


弱一致性


最终一致性

​ 是弱一致性的一种特例,在这种一致性下系统保证用户最终能够读取到某操作对系统特定数据的更新(读取操作之前没有该数据的其他更新操作)。”不一致性窗口”的大小依赖于交互延迟、系统的负载,以及数据的副本数等。

总结

​ 系统选择哪种一致性模型取决于应用对一致性的需求,所选取的一致性模型还会影响到系统如何处理用户的请求以及对副本维护技术的选择等。后面将基于上面介绍的一致性模型分别介绍分布式事务的解决方案。

柔性事务

柔性事务的概念

​ 在电商等互联网场景下,传统的事务在数据库性能和处理能力上都暴露出了瓶颈。在分布式领域基于CAP理论以及BASE理论,有人就提出了柔性事务的概念。

​ 基于BASE理论的设计思想,柔性事务下,在不影响系统整体可用性的情况下(Basically Available 基本可用),允许系统存在数据不一致的中间状态(Soft State 软状态),在经过数据同步的延时之后,最终数据能够达到一致。并不是完全放弃了ACID,而是通过放宽一致性要求,借助本地事务来实现最终分布式事务一致性的同时也保证系统的吞吐

实现柔性事务的一些特性

下面介绍的是实现柔性事务的一些常见特性,这些特性在具体的方案中不一定都要满足,因为不同的方案要求不一样。

可见性(对外可查询)

​ 在分布式事务执行过程中,如果某一个步骤执行出错,就需要明确的知道其他几个操作的处理情况,这就需要其他的服务都能够提供查询接口,保证可以通过查询来判断操作的处理情况。

​ 为了保证操作的可查询,需要对于每一个服务的每一次调用都有一个全局唯一的标识,可以是业务单据号(如订单号)、也可以是系统分配的操作流水号(如支付记录流水号)。除此之外,操作的时间信息也要有完整的记录。

操作幂等性

​ 幂等性,其实是一个数学概念。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。也就是说,同一个方法,使用同样的参数,调用多次产生的业务结果与调用一次产生的业务结果相同。

​ 之所以需要操作幂等性,是因为为了保证数据的最终一致性,很多事务协议都会有很多重试的操作,如果一个方法不保证幂等,那么将无法被重试。幂等操作的实现方式有多种,如在系统中缓存所有的请求与处理结果、检测到重复操作后,直接返回上一次的处理结果等。

本文由教研团队发布。

如果本文对您有帮助,欢迎和;如果您有任何建议也可或,您的支持是我坚持创作的动力。

转载请注明出处!

摘要:当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。

本文分享自华为云社区《九种跨域方式实现原理咋回事》,作者:龙哥手记

一、什么是跨域?

1.什么是同源策略及其限制内容?

同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指”协议+域名+端口”三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

同源策略限制内容有:

  • Cookie、LocalStorage、IndexedDB 等存储性内容
  • DOM 节点
  • AJAX 请求发送后,结果被浏览器拦截了

但是有三个标签是允许跨域加载资源:

  • <img src=https://www.xujun.org/XXX>
  • <link href=https://www.xujun.org/XXX>
  • <script src=https://www.xujun.org/XXX>

2.常见跨域场景

当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。

特别说明两点:

第一:如果是协议和端口造成的跨域问题“前台”是无能为力的。

第二:在跨域问题上,仅仅是通过“URL的首部”来识别而不会根据域名对应的IP地址是否相同来判断。“URL的首部”可以理解为“协议, 域名和端口必须匹配”。

这里你或许有个疑问:请求跨域了,那么请求到底发出去没有?

跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。你可能会疑问明明通过表单的方式可以发起跨域请求,为什么 Ajax 就不会?因为归根结底,跨域是为了阻止用户读取到另一个域名下的内容,Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。但是表单并不会获取新的内容,所以可以发起跨域请求。同时也说明了跨域并不能完全阻止 CSRF,因为请求毕竟是发出去了。

二、跨域解决方案

1.jsonp

1) JSONP原理

利用 <script> 标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。

2) JSONP和AJAX对比

JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)

3) JSONP优缺点

JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。

4) JSONP的实现流程

  • 声明一个回调函数,其函数名(如show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
  • 创建一个<script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)。
  • 服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是show,它准备好的数据是show(‘我不爱你’)。
  • 最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作。

在开发中可能会遇到多个 JSONP 请求的回调函数名是相同的,这时候就需要自己封装一个 JSONP函数。

 

上面这段代码相当于向http://localhost:3000/say?wd=Iloveyou&callback=show这个地址请求数据,然后后台返回show(‘我不爱你’),最后会运行show()这个函数,打印出’我不爱你’

 

5) jQuery的jsonp形式

JSONP都是GET和异步请求的,不存在其他的请求方式和同步请求,且jQuery默认就会给JSONP的请求清除缓存。

 

2.cors

CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。

浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。

服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。

虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求和复杂请求。

1) 简单请求

只要同时满足以下两大条件,就属于简单请求

条件1:使用下列方法之一:

  • GET
  • HEAD
  • POST

条件2:Content-Type 的值仅限于下列三者之一:

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器; XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。

2) 复杂请求

不符合以上条件的请求就肯定是复杂请求了。

复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求,该请求是 option 方法的,通过该请求来知道服务端是否允许跨域请求。

我们用PUT向后台请求时,属于复杂请求,后台需做如下配置:

 

接下来我们看下一个完整复杂请求的例子,并且介绍下CORS请求相关的字段

 

上述代码由http://localhost:3000/index.html向http://localhost:4000/跨域请求,正如我们上面所说的,后端是实现 CORS 通信的关键。

3.postMessage

postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:

  • 页面和其打开的新窗口的数据传递
  • 多窗口之间消息传递
  • 页面与嵌套的iframe消息传递
  • 上面三个场景的跨域数据传递

postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

otherWindow.postMessage(message, targetOrigin, [transfer]);

  • message: 将要发送到其他 window的数据。
  • targetOrigin:通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串”*”(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。
  • transfer(可选):是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

接下来我们看个例子: http://localhost:3000/a.html页面向http://localhost:4000/b.html传递“我爱你”,然后后者传回”我不爱你”。

 

4.websocket

Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。

原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

我们先来看个例子:本地文件socket.html向localhost:3000发生数据和接受数据

 

5. Node中间件代理(两次跨域)

实现原理:同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。
代理服务器,需要做以下几个步骤:

  • 接受客户端请求 。
  • 将请求 转发给服务器。
  • 拿到服务器 响应 数据。
  • 将 响应 转发给客户端。

我们先来看个例子:本地文件index.html文件,通过代理服务器http://localhost:3000向目标服务器http://localhost:4000请求数据。

 

上述代码经过两次跨域,值得注意的是浏览器向代理服务器发送请求,也遵循同源策略,最后在index.html文件打印出{“title”:”fontend”,”password”:”123456″}

6.nginx反向代理

实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。

使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。

实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。

先下载nginx,然后将nginx目录下的nginx.conf修改如下:

 

最后通过命令行nginx -s reload启动nginx

 

7.window.name + iframe

window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。

其中a.html和b.html是同域的,都是http://localhost:3000;而c.html是http://localhost:4000

 

b.html为中间代理页,与a.html同域,内容为空。

 

总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

8.location.hash + iframe

实现原理: a.html欲与c.html跨域相互通信,通过中间页b.html来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。

具体实现步骤:一开始a.html给c.html传一个hash值,然后c.html收到hash值后,再把hash值传递给b.html,最后b.html将结果放到a.html的hash值中。

同样的,a.html和b.html是同域的,都是http://localhost:3000;而c.html是http://localhost:4000

 

9.document.domain + iframe

该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式。
只需要给页面添加 document.domain =’test.com’ 表示二级域名都相同就可以实现跨域。

实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

我们看个例子:页面a.zf1.cn:3000/a.html获取页面b.zf1.cn:3000/b.html中a的值

 

三、总结

  • CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案
  • JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
  • 不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。
  • 日常工作中,用得比较多的跨域方案是cors和nginx反向代理

 

关注,第一时间了解华为云新鲜技术~

摘要:Nginx作为一款高性能的Web代理和负载均衡服务器,往往会部署在一些互联网应用比较前置的位置。此时,我们就可以在Nginx上进行设置,对访问的IP地址和并发数进行相应的限制。

本文分享自华为云社区《【高并发】使用Nginx实现限流》,作者:冰 河。

Nginx作为一款高性能的Web代理和负载均衡服务器,往往会部署在一些互联网应用比较前置的位置。此时,我们就可以在Nginx上进行设置,对访问的IP地址和并发数进行相应的限制。

Nginx官方的限流模块

Nginx官方版本限制IP的连接和并发分别有两个模块:

  • limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”。
  • limit_req_conn 用来限制同一时间连接数,即并发限制。

limit_req_zone 参数配置

limit_req_zone参数说明


  • 第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址。
  • 第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息。
  • 第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m的。

  • 第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应。
  • 第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内。
  • 第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。

limit_req_zone示例


下面配置可以限制特定UA(比如搜索引擎)的访问:


其他参数


当服务器由于limit被限速或缓存时,配置写入日志。延迟的记录比拒绝的记录低一个级别。例子:limit_req_log_level notice延迟的的基本是info。


设置拒绝请求的返回值。值只能设置 400 到 599 之间。

ngx_http_limit_conn_module 参数配置

ngx_http_limit_conn_module 参数说明

这个模块用来限制单个IP的请求数。并非所有的连接都被计数。只有在服务器处理了请求并且已经读取了整个请求头时,连接才被计数。


一次只允许每个IP地址一个连接。


可以配置多个limit_conn指令。例如,以上配置将限制每个客户端IP连接到服务器的数量,同时限制连接到虚拟服务器的总数。


在这里,客户端IP地址作为关键。请注意,不是$ remote_addr,而是使用$ binary_remote_addr变量。 $ remote_addr变量的大小可以从7到15个字节不等。存储的状态在32位平台上占用32或64字节的内存,在64位平台上总是占用64字节。对于IPv4地址,$ binary_remote_addr变量的大小始终为4个字节,对于IPv6地址则为16个字节。存储状态在32位平台上始终占用32或64个字节,在64位平台上占用64个字节。一个兆字节的区域可以保持大约32000个32字节的状态或大约16000个64字节的状态。如果区域存储耗尽,服务器会将错误返回给所有其他请求。


当服务器限制连接数时,设置所需的日志记录级别。


设置拒绝请求的返回值。

Nginx限流实战

限制访问速率


上述规则限制了每个IP访问的速度为2r/s,并将该规则作用于根目录。如果单个IP在非常短的时间内并发发送多个请求,结果会怎样呢?

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们使用单个IP在10ms内发并发送了6个请求,只有1个成功,剩下的5个都被拒绝。我们设置的速度是2r/s,为什么只有1个成功呢,是不是Nginx限制错了?当然不是,是因为Nginx的限流统计是基于毫秒的,我们设置的速度是2r/s,转换一下就是500ms内单个IP只允许通过1个请求,从501ms开始才允许通过第二个请求。

burst缓存处理

我们看到,我们短时间内发送了大量请求,Nginx按照毫秒级精度统计,超出限制的请求直接拒绝。这在实际场景中未免过于苛刻,真实网络环境中请求到来不是匀速的,很可能有请求“突发”的情况,也就是“一股子一股子”的。Nginx考虑到了这种情况,可以通过burst关键字开启对突发请求的缓存处理,而不是直接拒绝。

来看我们的配置:


我们加入了burst=4,意思是每个key(此处是每个IP)最多允许4个突发请求的到来。如果单个IP在10ms内发送6个请求,结果会怎样呢?

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

相比实例一成功数增加了4个,这个我们设置的burst数目是一致的。具体处理流程是:1个请求被立即处理,4个请求被放到burst队列里,另外一个请求被拒绝。通过burst参数,我们使得Nginx限流具备了缓存处理突发流量的能力。

但是请注意:burst的作用是让多余的请求可以先放到队列里,慢慢处理。如果不加nodelay参数,队列里的请求不会立即处理,而是按照rate设置的速度,以毫秒级精确的速度慢慢处理。

nodelay降低排队时间

在使用burst缓存处理中,我们看到,通过设置burst参数,我们可以允许Nginx缓存处理一定程度的突发,多余的请求可以先放到队列里,慢慢处理,这起到了平滑流量的作用。但是如果队列设置的比较大,请求排队的时间就会比较长,用户角度看来就是RT变长了,这对用户很不友好。有什么解决办法呢?nodelay参数允许请求在排队的时候就立即被处理,也就是说只要请求能够进入burst队列,就会立即被后台worker处理,请注意,这意味着burst设置了nodelay时,系统瞬间的QPS可能会超过rate设置的阈值。nodelay参数要跟burst一起使用才有作用。

延续burst缓存处理的配置,我们加入nodelay选项:


单个IP 10ms内并发发送6个请求,结果如下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

跟burst缓存处理相比,请求成功率没变化,但是总体耗时变短了。这怎么解释呢?在burst缓存处理中,有4个请求被放到burst队列当中,工作进程每隔500ms(rate=2r/s)取一个请求进行处理,最后一个请求要排队2s才会被处理;这里,请求放入队列跟burst缓存处理是一样的,但不同的是,队列中的请求同时具有了被处理的资格,所以这里的5个请求可以说是同时开始被处理的,花费时间自然变短了。

但是请注意,虽然设置burst和nodelay能够降低突发请求的处理时间,但是长期来看并不会提高吞吐量的上限,长期吞吐量的上限是由rate决定的,因为nodelay只能保证burst的请求被立即处理,但Nginx会限制队列素释放的速度,就像是限制了令牌桶中令牌产生的速度。

看到这里你可能会问,加入了nodelay参数之后的限速算法,到底算是哪一个“桶”,是漏桶算法还是令牌桶算法?当然还算是漏桶算法。考虑一种情况,令牌桶算法的token为耗尽时会怎么做呢?由于它有一个请求队列,所以会把接下来的请求缓存下来,缓存多少受限于队列大小。但此时缓存这些请求还有意义吗?如果server已经过载,缓存队列越来越长,RT越来越高,即使过了很久请求被处理了,对用户来说也没什么价值了。所以当token不够用时,最明智的做法就是直接拒绝用户的请求,这就成了漏桶算法。

自定义返回值


默认情况下 没有配置 status 返回值的状态:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

关注,第一时间了解华为云新鲜技术~

作者:京东零售 栗鸿宇

1.png

ChatGPT简介

ChatGPT是一款基于AI技术的机器人对话软件,它能够与用户进行智能化的聊天对话,帮助用户解决日常生活中的问题,为用户提供丰富的信息和服务。它集成了海量知识库,能够回答用户的各种问题,包括日常生活中的常识性问题、文理科专业问题等,并且能够根据用户的需求提供个性化的信息服务。

同时,ChatGPT还拥有强大的学习能力,通过收集互联网上海量的文本资源,并在交流中不断地学习用户的交流习惯和语言表达方式,从而不断优化自身的对话能力,让用户在使用ChatGPT时感到越来越自然和舒适。

总之,ChatGPT是一款先进的机器人对话软件,能够为用户提供丰富的信息和服务,让用户在日常生活中获得更多便利和乐趣。

让ChatGPT自己介绍一下自己:



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)





训练机制

官方博客中介绍到,ChatGPT是基于GPT-3.5(模型card:https://datalearner.com/ai-resources/pretrained-models/gpt-3-5 )微调的结果。ChatGPT是InstructGPT的兄弟模型(InstructGPT是官方训练的一个比GPT-3更好的遵循用户意图的语言模型,是基于OpenAI的alignment research技术研发的,比GPT-3更强的语言模型)。ChatGPT的训练使用了基于人类反馈的强化学习( Reinforcement Learning from Human Feedback,RLHF)。这点与InstructGPT一样,但是在数据收集方面有差异。OpenAI使用监督下的微调训练了一个初始模型:人类人工智能trainer提供对话,他们在对话中扮演双方—用户和人工智能助理。这可以让训练者接触到模型编写的建议,以帮助组成对应的回应。



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



编程能力

目前几家硅谷大厂都在朝着AI自动化编程努力:

•DeepMind的AlphaCode,据说「吊打72%人类程序员」,但尚未开放;

•传闻中谷歌的「神秘项目」Pitchfork,也还在酝酿中;

•前段时间大火的GitHub Copilot主要是一个代码补全工具。

但是要说以上工具完全代替人类程序员,它们还不够格😕。那么号称能学习人类思维来编程的ChatGPT能做到什么程度呢?

笔者首先丢给他一个LeetCode上经典的Hard难度问题:接雨水( https://leetcode.cn/problems/trapping-rain-water/ )

我在提问时并没有说明这是一道编程题,ChatGPT也能够正确识别并回答,说明拥有了一些理解提问者思想的能力😯。不到10秒钟,他就给出来了相应的示例代码,而且代码在leetcode上是可以AC的



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



但是上面的这些问题是不是直接通过搜索引擎搜出来,甚至是从AC的Solution里面摘抄出来的呢?🤔

接着我给了一个面试时经常会问到的SQL问题:



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



这种应该就不是搜出来的,但是AI算法经过学习还是能够理解并写出答案。虽然这段代码还不能拿过来直接使用,但是基本逻辑是正确的,开发者可以按照真实的表结构修改后使用。

在回答的最后,ChatGPT甚至还会简单分析下代码的逻辑,因此这款工具对于理解复杂算法提供了很好的辅助手段😏。

作为实验,我又让他解释了下快速排序的时间复杂度:



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



可以看出虽然解释的内容相对简单,但是对于有一定基础的人还是可以快速理解的。

所以各位远程面试的面试官要小心咯!因为你不知道电话另一边的回答是不是来自于一个机器人的手笔😱😱

程序员终结者?

我在日常沟通、专业解答、编程方案等方面和ChatGPT聊了很久,发现这个AI确实要比之前那些聊天机器人强很多,大多数情况下给出的回答都能够符合预期😬



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)





但是聊得多了就能发现,ChatGPT解决问题的策略更像是一个优秀的答案缝合思路,看到题目先联想是否做过类似的,然后通过已知的答案缝合成另一个答案,所以我觉得现阶段ChatGPT让大量程序员失业还不太可能😎



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)





从已有的成果和调研来看,AI绘画出的图片(如Deep Dream、stable diffusion)可以抵得上很多有较长练习经验的人的水平,但是chatGPT输出的程序尚且达不到中高级程序员的可靠性,而且其给出的代码全部是方法级、片段式的,无法直接满足一个完整需求。如果把AI当做是一个私人助理,chatGPT是合格的,虽然他说的很多都是车轱辘话,但是也能保证说出的是“正确的,客观的,中肯的…”,尤其是针对编程问题和理科问题, 大部分时候给出的建议还是挺靠谱的 (不靠谱的回答会非常明显,一眼看穿)。

因此,作为一个类似于Siri或是Google Assistant的聊天机器人来说,是绝对比之前的AI好的,但是拿来写代码,我觉得基本上不太可能。因为程序员的工作不仅仅需要写代码,更需要遵循逻辑、根据复杂的需求场景构思出符合要求的完整工程。另外,根据我自身对于ChatGPT的测试结果来看,目前阶段,靠ChatGPT去写代码还不如靠搜索引擎,最多能看作一个助手,对于广大程序员来说是一个不错的辅助工具。

至于替代程序员的工作,只能说如果有人如果能被这玩意替代,应该也找不到什么好工作……

但是,这AI写车轱辘话的水平一流!营销号狂喜!🤣🤣



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)





注册使用流程

😡技术有国界,想玩用梯子😡

要注册使用 ChatGPT,我们需要准备以下内容:

•能够访问Google的全局代理,推荐美国节点(实测亚洲节点如香港、新加坡节点会被ban);

•一个邮箱用于注册,如Gmail,Outlook;

•一个国外手机号,如果没有可以在第1步中通过第三方接码平台来完成注册

1. 账号注册

进入注册页面:https://chat.openai.com/auth/login



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



注册按钮,输入邮箱,还有你的注册账号,并设置密码



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



邮箱确认好之后,接下来要填入电话。



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



这里请大家注意,中国区的+86是不行的,如果你用GoogleVoice的话,也会被判别是虚拟电话,而做不了验证码。

需要通过下方平台接收短信

2. 使用第三方接码平台

打开网站:https://sms-activate.org/cn



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)





右上角的注册按钮,在注册页面输入自己的邮箱账号,设置密码后提交。会给你的邮箱发一条验证邮件,邮件中的链接确认即完成注册。

我们注册后登录,在「余额」那里「充值」,使用支付宝充值 0.2 美金即可



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)





然后,回到首页,搜索并选择OpenAi服务,加车后购买即可



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)





3. 使用购买的号码激活

购买完成后,然后就可以在激活区域看到待使用的号码。

复制这个号码,然后把这个号码放在第1步最后的验证码接收区

接收验证码按钮后,可以回到第三方接码平台网站,看到验证码(从上面的截图中应该能够看到我有一个印度号码的使用记录),再次复制这个验证码填进去,这样就成功完成注册了



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



注册完后,就可以ChatGPT网站去登陆:

https://chat.openai.com/auth/login

大家快去调戏ChatGPT吧~~

导读

随着Stable Diffusion模型在AI圈的爆火,AI生成内容(AI Generated Content,AIGC)的应用呈现出井喷式的增长趋势。其中,文图生成(Text-to-image Generation)任务是最流行的AIGC任务之一,旨在生成与给定文本对应的图像。在先前的工作中,阿里云机器学习PAI团队开源了PAI-Diffusion系列模型(看这里),包括一系列通用场景和特定场景的文图生成模型,例如古诗配图、二次动漫、魔幻现实等。这些模型的Pipeline除了包括标准的Latent Diffusion Model,还集成了PAI团队先前提出的中文CLIP跨模态对齐模型(看这里),及图像超分模型,使得模型可以生成符合中文文本描述的、各种场景下的高清大图。由于在特定场景下,用户往往有对这些中文Diffusion模型调优(Fine-tune)的需求,而且在线上部署方面,由于Diffusion模型推理速度比较慢,而且需要耗费较多的硬件资源。在本次的工作中,我们在EasyNLP算法框架中,对先前提出的PAI-Diffusion模型功能进行升级,全链路支持模型调优。在模型推理方面,结合由PAI自主研发的编译优化工具 PAI-Blade,支持对PAI-Diffusion模型的端到端的导出和推理加速,在A10机器下做到了1s内的中文大图生成。

本⽂首先介绍如何体验PAI-Diffusion模型以及其在线部署、加速推理能力。其次,我们简单回顾了PAI-Diffusion模型的架构,之后详细介绍了在EasyNLP算法框架中对上述模型进行调优的全链路支持。

轻松体验PAI-Diffusion模型

首先让我们轻松体验PAI-Diffusion模型。

在线体验

PAI-Diffusion模型可以用于各种风格的艺术画的生成。这个模型的参数量仅10亿,使用一张P100 GPU显卡,就可以生成1024*1024的高清大图,示例如下。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们在AI模型开源社区ModelScope的创空间上线了我们的一个PAI-Diffusion模型(体验链接),欢迎广大用户体验。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

PAI-Diffusion模型架构回顾

我们简单回顾一下PAI-Diffusion模型的技术架构。简单的说,PAI-Diffusion模型是面向中文的、基于隐式扩散模型(Latent Diffusion Model, LDM)的文图生成模型。因为中英文在文化和表达上具有很大的差异性,产出的模型通常无法建模中文特有的现象。PAI-Diffusion模型由阿里云机器学习(PAI)团队发布并开源,除了可以用于通用文图生成场景,还具有一系列特定场景的定制化中文Diffusion模型,包括古诗配图、二次动漫、魔幻现实等。PAI-Diffusion的模型Pipeline架构,包括中文CLIP模型、Diffusion模型、图像超分模型等:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

具体地说,中文CLIP模型把中文文本输入转化成 Embedding 向量,我们采用EasyNLP中文CLIP跨模态对齐模型(看这里)的Text Transformer作为Text Encoder。我们把中文CLIP模型的输出作为LDM的输入,训练模型生成文本对应的图片。可选地,PAI-Diffusion模型链路中还集成了ESRGAN作为图像超分模型,提升图片的分辨率。

PAI-Diffusion模型加速推理技术

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

PAI-Blade采用以AI编译器为主线的技术路径,支持在多种框架、多种硬件上进行机器学习模型的优化。其核心组件BladeDISC是一款支持动态Shape的深度学习编译器,并已在GitHub开源(https://github.com/alibaba/BladeDISC)。

image.png

上图为PAI-Diffusion端到端生成一张图片的各部分时间占比,由图可知,该模型的主要开销来自UNet中的Resnet Block和Attention Block。针对不同类型的深度学习 workload,BladeDISC有相应的技术进行针对性优化。针对计算密集型部分,BladeDISC内置BladNN可以提供高性能的算子实现;针对访存密集型部分,aStitch则可以对访存密集型算子进行大尺度的融合;同时,由于BladeDISC原生支持动态Shape,优化完的模型可以输出不同尺寸的图片。

通过对PAI-Diffusion模型和社区的Stable-Diffusion模型的推理进行测速分析,PAI-Blade 优化之后成功将整个推理链路平均提速75%以上,具体加速比视推理步数略有不同,详细可以参考下表(测试推理机器 Nvidia-A10,输出图片分辨率 512×512):

pai-diffusion原版 pai-blade 加速后 加速比 采样步数 1.61s 0.97s 66% 20 3.02s 1.62s 86% 50

综上可以看到, 引入PAI-Blade 能大幅度提升DiffusionModel的推理速度,降低服务延迟,节省计算资源。

PAI-Diffusion模型的微调和微调后模型部署

在本次更新中,我们在PAI-EasyNLP算法框架对PAI-Diffusion模型的调优做了全面支持。我们介绍如何在PAI-Diffusion模型的训练流程,以及如何在PAI的产品中部署上述微调后的模型用于在线服务。

安装EasyNLP

用户可以直接参考链接的说明安装EasyNLP算法框架。

数据准备

首先准备训练数据与验证数据,为tsv文件。这⼀⽂件包含以制表符 分隔的三列(idx, text, imgbase64),第一列是文本编号,第二列是文本,第三列是对应图片的base64编码。样例如下:

 

为了方便开发者,我们也提供了转换图片到base64编码的示例代码:

 

下列文件已经完成预处理,可用于测试:

 

模型微调

我们采用以下命令对PAI-Diffusion模型进行fine-tune:

 

训练完成后模型被保存到https://www.xujun.org/finetune_model/。

模型离线推理

模型训练完毕后,我们可以将其用于图片的生成,示例如下:

 

直接在线部署

用户可以使用PAI-EAS自定义服务部署方式,使用如下config部署我们已经打包好的相关processor进行服务部署即可。我们提供了一个测试模型以供体验模型的推理速度,部署在A10/T4/V100 GPU的config参考如下,您需要将resource字段替换成自己的资源组:

 

如果您需要体验Blade优化后的推理速度,可以在A10 GPU中进行部署,用户需要将上述model_path的值替换为http://pai-vision-exp.oss-cn-zhangjiakou.aliyuncs.com/wzh-zhoulou/dl_eas_processor/ch_ldm/ch_ldm_blade_/eas_model_.tar.gz。

当服务部署成功后,可以使用如下格式的request body进行测试:

 

在线服务返回示例如下:

 

images_base64字段返回生成图像的base64编码,生成图像数量由request body中的参数指定。

微调后部署

用户也可以使用EasyNLP进行微调训练后部署,需要将如下训练后的ckpt 打包替换上面json中的model_path字段:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

打包命令示例如下:

 

然后,采用前述config 将模型部署到PAI-EAS,建议使用的GPU型号为A10/T4/V100。

如果用户需要使用Blade 加速,支持使用A10/A100 GPU机器资源进行部署,请联系我们获取Blade相关教程。

未来展望

在这一期的工作中,我们对PAI-Diffusion模型的功能进行重大升级,在EasyNLP框架中(https://github.com/alibaba/EasyNLP)支持全链路模型的调优和在线部署,使得用户能一键实现模型的调优,并且在阿里云PAI平台上便捷部署在线服务。此外,阿里云机器学习PAI团队也在持续推进中文多模态模型的自研工作,欢迎用户持续关注我们,也欢迎加入我们的开源社区,共建中文NLP和多模态算法库!

Github地址:https://github.com/alibaba/EasyNLP

Reference

  1. Chengyu Wang, Minghui Qiu, Taolin Zhang, Tingting Liu, Lei Li, Jianing Wang, Ming Wang, Jun Huang, Wei Lin. EasyNLP: A Comprehensive and Easy-to-use Toolkit for Natural Language Processing. EMNLP 2022
  2. Robin Rombach, Andreas Blattmann, Dominik Lorenz, Patrick Esser, Björn Ommer. High-Resolution Image Synthesis with Latent Diffusion Models. CVPR 2022
  3. Alec Radford, Jong Wook Kim, Chris Hallacy, Aditya Ramesh, Gabriel Goh, Sandhini Agarwal, Girish Sastry, Amanda Askell, Pamela Mishkin, Jack Clark, Gretchen Krueger, Ilya Sutskever. Learning Transferable Visual Models From Natural Language Supervision. ICML 2021

EasyNLP阿里灵杰回顾

EasyNLP是阿里云机器学习PAI 团队基于 PyTorch 开发的易用且丰富的中文NLP算法框架,支持常用的中文预训练模型和大模型落地技术,并且提供了从训练到部署的一站式 NLP 开发体验。EasyNLP 提供了简洁的接口供用户开发 NLP 模型,包括NLP应用 AppZoo 和预训练 ModelZoo,同时提供技术帮助用户高效的落地超大预训练模型到业务。由于跨模态理解需求的不断增加,EasyNLP也将支持各种跨模态模型,特别是中文领域的跨模态模型,推向开源社区,希望能够服务更多的 NLP 和多模态算法开发者和研究者,也希望和社区一起推动 NLP /多模态技术的发展和模型落地。

  • 阿里灵杰:阿里云机器学习PAI开源中文NLP算法框架EasyNLP,助力NLP大模型落地
  • 阿里灵杰:预训练知识度量比赛夺冠!阿里云PAI发布知识预训练工具
  • 阿里灵杰:EasyNLP带你玩转CLIP图文检索
  • 阿里灵杰:EasyNLP中文文图生成模型带你秒变艺术家
  • 阿里灵杰:EasyNLP集成K-BERT算法,借助知识图谱实现更优Finetune
  • 阿里灵杰:中文稀疏GPT大模型落地 — 通往低成本&高性能多任务通用自然语言理解的关键里程碑
  • 阿里灵杰:EasyNLP玩转文本摘要(新闻标题)生成
  • 阿里灵杰:跨模态学习能力再升级,EasyNLP电商文图检索效果刷新SOTA
  • 阿里灵杰:EasyNLP带你实现中英文机器阅读理解
  • 阿里灵杰:EasyNLP发布融合语言学和事实知识的中文预训练模型CKBERT
  • 阿里灵杰:当大火的文图生成模型遇见知识图谱,AI画像趋近于真实世界
  • 阿里灵杰:PAI-Diffusion模型来了!阿里云机器学习团队带您徜徉中文艺术海洋

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在 Databend 中按函数实现分为了:scalars 函数和 aggregates 函数。

Scalar 函数: 基于输入值,返回单个值。常见的 Scalar function 有 now, round 等。

Aggregate 函数: 用于对列的值进行操作并返回单个值。常见的 Agg function 有 sum, count, avg 等。

https://github.com/datafuselabs/databend/tree/main/src/query/functions/src

该系列共两篇,本文主要介绍 Scalar Function 从注册到执行是如何在 Databend 运行起来的。

函数注册

由 FunctionRegistry 接管函数注册。


三个 item 都是 Hashmap。

其中,funcs 和 factories 都用来存储被注册的函数。不同之处在于 funcs 注册的都是固定参数个数的函数(目前支持最少参数个数为0,最多参数个数为 5),分为 register_0_arg, register_1_arg 等等。而 factories 注册的都是参数不定长的函数(如 concat),调用 register_function_factory 函数。

由于一个函数可能有多个别名(如 minus 的别名有 subtract 和 neg),因此有了 alias,它的 key 是某个函数的别名,v 是当前的存在的函数名,调用 register_aliases 函数。

另外, 根据不同的功能需求, 我们提供了不同级别的 register api。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

函数构成

已知 funcs 的 value 是函数主体,我们来看一下 Function 在 Databend 中是怎么构建的。


其中, 包括 函数名,参数类型,返回类型以及函数特性(目前暂未有函数使用特性,仅作为保留位)。要特别注意的是,在注册时函数名需要是小写。而一些 token 会经过 src/query/ast/src/parser/token.rs 转换。


以实现 `select 1+2` 的加法函数为例子,`+` 被转换为 Plus,而函数名需要小写,因此我们在注册时函数名使用 `plus`。


calc_domain 用来计算输出值的输入值的集合。用数学公式描述的话比如 `y = f(x)` 其中域就是 x 值的集合,可以作为f的参数生成 y 值。这可以使我们在索引数据时轻松过滤掉不在域内的值,极大提升响应效率。

eval 可以理解成函数的具体实现内容。本质是接受一些字符或者数字,将他们解析成表达式,再转换成另外一组值。

示例

目前在 function-v2 中实现的函数有这几类:arithmetric, array, boolean, control, comparison, datetime, math, string, string_mult_args, variant

以 length 的实现为例:

length 接受一个 String 类型的值为参数,返回一个 Number 类型。名字为 length,domain 不做限制(因为任何 string 都有长度)最后一个参数是一个闭包函数,作为 length 的 eval 实现部分。


在 register_1_arg 的实现中,我们看到调用的函数是 register_passthrough_nullable_1_arg,函数名包含一个 nullable。而 eval 被 vectorize_1_arg 调用。

注意:请不要手动修改 register_1_arg 所在的文件 [src/query/expression/src/register.rs](https://github.com/datafuselabs/databend/blob/2aec38605eebb7f0e1717f7f54ec52ae0f2e530b/src/query/expression/src/register.rs) 。因为它是被 [src/query/codegen/src/writes/register.rs](https://github.com/datafuselabs/databend/blob/2aec38605eebb7f0e1717f7f54ec52ae0f2e530b/src/query/codegen/src/writes/register.rs) 生成的。


这是因为 eval 在实际应用场景中接受的不只是字符或者数字,还可能是 null 或者其他各种类型。而 null 无疑是最特殊的一种。而我们接收的参数也可能是一个列或者一个值。比如


基于此,如果我们在函数中无需对 null 类型的值做特殊处理,直接使用 register_x_arg 即可。如果需要对 null 类型做特殊处理,参考 [try_to_timestamp](https://github.com/datafuselabs/databend/blob/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/src/query/functions/src/scalars/datetime.rs)。

而对于需要在 vectorize 中进行特化的函数则需要调用 register_passthrough_nullable_x_arg,对要实现的函数进行特定的向量化优化。

例如 comparison 函数 regexp 的实现:regexp 接收两个 String 类型的值,返回 Bool 值。在向量化执行中,为了进一步优化减少重复正则表达式的解析,引入了 HashMap 结构。因此单独实现了 `vectorize_regexp`。


函数测试

Unit Test

函数相关单测试在 [scalars](https://github.com/datafuselabs/databend/tree/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/src/query/functions/tests/it/scalars) 目录中。

Logic Test

Functions 相关的 logic 测试在 [02_function](https://github.com/datafuselabs/databend/tree/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/tests/sqllogictests/suites/query/02_function) 目录中。

关于 Databend

Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。

  • Databend 文档:https://databend.rs/

  • Twitter:https://twitter.com/Datafuse_Labs

  • Slack:https://datafusecloud.slack.com/

  • Wechat:Databend

  • GitHub :https://github.com/datafuselabs/databend

作者:京东科技 文涛

前言

软件研发工程师俗称程序员经常对业界外的人自谦作码农,一来给自己不菲的收入找个不错的说辞(像农民伯伯那样辛勤耕耘挣来的血汗钱),二来也是自嘲这个行业确实辛苦,辛苦得没时间捯饬,甚至没有驼背、脱发加持都说不过去。不过时间久了,行外人还真就相信了程序员就是一帮没品味,木讷的low货,大部分的文艺作品中也都是这么表现程序员的。可是我今天要说一下我的感受,编程是个艺术活,程序员是最聪明的一群人,我们的品味也可以像艺术家一样。

言归正转,你是不是以为我今天要教你穿搭?不不不,这依然是一篇技术文章,想学穿搭女士学陈舒婷(《狂飙》中的大嫂),男士找陈舒婷那样的女朋友就好了。笔者今天教你怎样有“品味”的写代码。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



以下几点可提升“品味”

说明:以下是笔者的经验之谈具有部分主观性,不赞同的欢迎拍砖,要想体系化提升编码功底建议读《XX公司Java编码规范》、《Effective Java》、《代码整洁之道》。以下几点部分具有通用性,部分仅限于java语言,其它语言的同学绕过即可。

优雅防重

关于成体系的防重讲解,笔者之后打算写一篇文章介绍,今天只讲一种优雅的方式:

如果你的业务场景满足以下两个条件:

1 业务接口重复调用的概率不是很高

2 入参有明确业务主键如:订单ID,商品ID,文章ID,运单ID等

在这种场景下,非常适合乐观防重,思路就是代码处理不主动做防重,只在监测到重复提交后做相应处理。

如何监测到重复提交呢?MySQL唯一索引 + org.springframework.dao.DuplicateKeyException

代码如下:




用好lambda表达式

lambda表达式已经是一个老生常谈的话题了,笔者认为,初级程序员向中级进阶的必经之路就是攻克lambda表达式,lambda表达式和面向对象编程是两个编程理念,《架构整洁之道》里曾提到有三种编程范式,结构化编程(面向过程编程)、面向对象编程、函数式编程。初次接触lambda表达式肯定特别不适应,但如果熟悉以后你将打开一个编程方式的新思路。本文不讲lambda,只讲如下例子:

比如你想把一个二维表数据进行分组,可采用以下一行代码实现




用好卫语句

各个大场的JAVA编程规范里基本都有这条建议,但我见过的代码里,把它用好的不多,卫语句对提升代码的可维护性有着很大的作用,想像一下,在一个10层if 缩进的接口里找代码逻辑是一件多么痛苦的事情,有人说,哪有10层的缩进啊,别说,笔者还真的在一个微服务里的一个核心接口看到了这种代码,该接口被过多的人接手导致了这样的局面。系统接手人过多以后,代码腐化的速度超出你的想像。

下面举例说明:

没有用卫语句的代码,很多层缩进


使用了卫语句的代码,缩进很少


避免双重循环

简单说双重循环会将代码逻辑的时间复杂度扩大至O(n^2)

如果有按key匹配两个列表的场景建议使用以下方式:

1 将列表1 进行map化

2 循环列表2,从map中获取值

代码示例如下:


用@see @link来设计RPC的API

程序员们还经常自嘲的几个词有:API工程师,中间件装配工等,既然咱平时写API写的比较多,那种就把它写到极致@see @link的作用是让使用方可以方便的链接到枚举类型的对象上,方便阅读

示例如下:


日志打印避免只打整个参数

研发经常为了省事,直接将入参这样打印


该日志进了日志系统后,研发在搜索日志的时候,很难根据业务主键排查问题

如果改进成以下方式,便可方便的进行日志搜索


如上:只需要全词匹配“operateRelationParam,id:111”,即可找到业务主键111的业务日志。

用异常捕获替代方法参数传递

我们经常面对的一种情况是:从子方法中获取返回的值来标识程序接下来的走向,这种方式笔者认为不够优雅。

举例:以下代码paramCheck和deleteContent方法,返回了这两个方法的执行结果,调用方通过返回结果判断程序走向


我们可以通过自定义异常的方式解决:子方法抛出不同的异常,调用方catch不同异常以便进行不同逻辑的处理,这样调用方特别清爽,不必做返回结果判断

代码示例如下:


自定义SpringBoot的Banner

别再让你的Spring Boot启动banner千篇一律,spring 支持自定义banner,该技能对业务功能实现没任何卵用,但会给枯燥的编程生活添加一点乐趣。

以下是官方文档的说明: https://docs.spring.io/spring-boot/docs/1.3.8.RELEASE/reference/htmlsingle/#boot-features-banner

另外你还需要ASCII艺术字生成工具: https://tools.kalvinbg.cn/txt/ascii

效果如下:


多用Java语法糖

编程语言中java的语法是相对繁琐的,用过golang的或scala的人感觉特别明显。java提供了10多种语法糖,写代码常使用语法糖,给人一种 “这哥们java用得通透” 的感觉。

举例:try-with-resource语法,当一个外部资源的句柄对象实现了AutoCloseable接口,JDK7中便可以利用try-with-resource语法更优雅的关闭资源,消除板式代码。


利用链式编程

链式编程,也叫级联式编程,调用对象的函数时返回一个this对象指向对象本身,达到链式效果,可以级联调用。链式编程的优点是:编程性强、可读性强、代码简洁。

举例:假如觉得官方提供的容器不够方便,可以自定义,代码如下,但更建议使用开源的经过验证的类库如guava包中的工具类


未完,待续,欢迎评论区补充

作者:京东科技 张天赐

前言

JDK 8 是一次重大的版本升级,新增了非常多的特性,其中之一便是 。自此从 JDK 层面真正意义上的支持了基于事件的异步编程范式,弥补了  的缺陷。

在我们的日常优化中,最常用手段便是多线程并行执行。这时候就会涉及到  的使用。

常见使用方式

下面举例一个常见场景。

假如我们有两个 RPC 远程调用服务,我们需要获取两个 RPC 的结果后,再进行后续逻辑处理。


可以预估到,串行执行最少耗时 4 秒,并且 B 任务并不依赖 A 任务结果。

对于这种场景,我们通常会选择并行的方式优化,Demo 代码如下:


可以看到耗时变成了 2 秒。

存在的问题

分析

看上去  现有功能可以满足我们诉求。但当我们引入一些现实常见情况时,一些潜在的不足便暴露出来了。

 如果是一个根据入参查询用户某类型优惠券列表的任务,我们需要查询两种优惠券并组合在一起返回给上游。假如上游要求我们 2 秒内处理完毕并返回结果,但  耗时却在 0.5 秒 ~ 无穷大波动。这时候我们就需要把耗时过长的  任务结果放弃,仅处理在指定时间内完成的任务,尽可能保证服务可用。

那么以上代码的耗时由耗时最长的服务决定,无法满足现有诉求。通常我们会使用  来指定获取结果的超时时间,并且我们会给  设置一个超时时间,达到后自动抛异常来中断任务。


可以看到,只要我们能够给  设置一个超时时间将任务中断,结合 、 等获取结果的方式,就可以很好地管理整体耗时。

那么问题也就转变成了,如何给任务设置异步超时时间呢

现有做法

当异步任务是一个 RPC 请求时,我们可以设置一个 JSF 超时,以达到异步超时效果。

当请求是一个 R2M 请求时,我们也可以控制 R2M 连接的最大超时时间来达到效果。

这么看好像我们都是在依赖三方中间件的能力来管理任务超时时间?那么就存在一个问题,中间件超时控制能力有限,如果异步任务是中间件 IO 操作 + 本地计算操作怎么办?

用 JSF 超时举一个具体的例子,反编译 JSF 的获取结果代码如下:


当这个任务刚好卡在超时边缘完成时,这个任务的耗时时间就变成了超时时间 + 获取结果时间。而获取结果(反序列化)作为纯本地计算操作,耗时长短受 CPU 影响较大。

某些 CPU 使用率高的情况下,就会出现异步任务没能触发抛出异常中断,导致我们无法准确控制超时时间。对上游来说,本次请求全部失败。

解决方式

JDK 9

这类问题非常常见,如大促场景,服务器 CPU 瞬间升高就会出现以上问题。

那么如何解决呢?其实 JDK 的开发大佬们早有研究。在 JDK 9, 正式提供了 、 方法,来准确实现异步超时控制。


JDK 9  其实现原理是通过一个定时任务,在给定时间之后抛出异常。如果任务在指定时间内完成,则取消抛异常的操作。

以上代码我们按执行顺序来看下:

首先执行 。


通过源码可以看到, 是一个实现 Runnable 的类, 方法负责给传入的异步任务通过  CAS 赋值异常,将任务标记为异常完成。

那么谁来触发这个  方法呢?我们看下  的实现。


 其实就是一个单例定时调度器, 通过  实现指定时间后触发  的  方法。

到这里就已经实现了超时抛出异常的操作。但当任务完成时,就没必要触发  了。因此我们还需要实现一个取消逻辑。


当任务执行完成,或者任务执行异常时,我们也就没必要抛出超时异常了。因此我们可以把  返回的定时超时任务取消,不再触发 。 当我们的异步任务完成,并且定时超时任务未完成的时候,就是我们取消的时机。因此我们可以通过  来完成。

 就是一个  的实现。其持有了  返回的定时超时任务, 实现了定时超时任务未完成后,执行  取消任务的操作。

JDK 8

如果我们使用的是 JDK 9 或以上,我们可以直接用 JDK 的实现来完成异步超时操作。那么 JDK 8 怎么办呢?

其实我们也可以根据上述逻辑简单实现一个工具类来辅助。

以下是我们营销自己的工具类以及用法,贴出来给大家作为参考,大家也可以自己写的更优雅一些~

调用方式:


工具类源码:


参考资料

  1. JEP 266: JDK 9 并发包更新提案

作者:京东科技 王晨

Redis异步客户端选型及落地实践

可视化服务编排系统是能够通过线上可视化拖拽、配置的方式完成对接口的编排,可在线完成服务的调试、测试,实现业务需求的交付,详细内容可参考:https://sigusoft.com/s/5oN9JqWN7n-4Zv6B9K8kWQ。

为了支持更加广泛的业务场景,可视化编排系统近期需要支持对缓存的操作功能,为保证编排系统的性能,服务的执行过程采用了异步的方式,因此我们考虑使用Redis的异步客户端来完成对缓存的操作。

Redis客户端

Jedis/Lettuce

Redis官方推荐的Redis客户端有Jedis、Lettuce等等,其中Jedis 是老牌的 Redis 的 Java 实现客户端,提供了比较全面的 Redis 命令的支持,在spring-boot 1.x 默认使用Jedis。

但是Jedis使用阻塞的 IO,且其方法调用都是同步的,程序流需要等到 sockets 处理完 IO 才能执行,不支持异步,在并发场景下,使用Jedis客户端会耗费较多的资源。

此外,Jedis 客户端实例不是线程安全的,要想保证线程安全,必须要使用连接池,每个线程需要时从连接池取出连接实例,完成操作后或者遇到异常归还实例。当连接数随着业务不断上升时,对物理连接的消耗也会成为性能和稳定性的潜在风险点。因此在spring-boot 2.x中,redis客户端默认改用了Lettuce。

我们可以看下 Spring Data Redis 帮助文档给出的对比表格,里面详细地记录了两个主流Redis客户端之间的差异。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

异步客户端Lettuce

Spring Boot自2.0版本开始默认使用Lettuce作为Redis的客户端。Lettuce客户端基于Netty的NIO框架实现,对于大多数的Redis操作,只需要维持单一的连接即可高效支持业务端的并发请求 —— 这点与Jedis的连接池模式有很大不同。同时,Lettuce支持的特性更加全面,且其性能表现并不逊于,甚至优于Jedis。

Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

上图展示了Netty NIO的核心逻辑。NIO通常被理解为non-blocking I/O的缩写,表示非阻塞I/O操作。图中Channel表示一个连接通道,用于承载连接管理及读写操作;EventLoop则是事件处理的核心抽象。一个EventLoop可以服务于多个Channel,但它只会与单一线程绑定。EventLoop中所有I/O事件和用户任务的处理都在该线程上进行;其中除了选择器Selector的事件监听动作外,对连接通道的读写操作均以非阻塞的方式进行 —— 这是NIO与BIO(blocking I/O,即阻塞式I/O)的重要区别,也是NIO模式性能优异的原因。

Lettuce凭借单一连接就可以支持业务端的大部分并发需求,这依赖于以下几个因素的共同作用:

1.Netty的单个EventLoop仅与单一线程绑定,业务端的并发请求均会被放入EventLoop的任务队列中,最终被该线程顺序处理。同时,Lettuce自身也会维护一个队列,当其通过EventLoop向Redis发送指令时,成功发送的指令会被放入该队列;当收到服务端的响应时,Lettuce又会以FIFO的方式从队列的头部取出对应的指令,进行后续处理。

2.Redis服务端本身也是基于NIO模型,使用单一线程处理客户端请求。虽然Redis能同时维持成百上千个客户端连接,但是在某一时刻,某个客户端连接的请求均是被顺序处理及响应的。

3.Redis客户端与服务端通过TCP协议连接,而TCP协议本身会保证数据传输的顺序性。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如此,Lettuce在保证请求处理顺序的基础上,天然地使用了管道模式(pipelining)与Redis交互 —— 在多个业务线程并发请求的情况下,客户端不必等待服务端对当前请求的响应,即可在同一个连接上发出下一个请求。这在加速了Redis请求处理的同时,也高效地利用了TCP连接的全双工特性(full-duplex)。而与之相对的,在没有显式指定使用管道模式的情况下,Jedis只能在处理完某个Redis连接上当前请求的响应后,才能继续使用该连接发起下一个请求。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在并发场景下,业务系统短时间内可能会发出大量请求,在管道模式中,这些请求被统一发送至Redis服务端,待处理完成后统一返回,能够大大提升业务系统的运行效率,突破性能瓶颈。R2M采用了Redis Cluster模式,在通过Lettuce连接R2M之前,应该先对Redis Cluster模式有一定的了解。

Redis Cluster模式

在redis3.0之前,如果想搭建一个集群架构还是挺复杂的,就算是基于一些第三方的中间件搭建的集群总感觉有那么点差强人意,或者基于sentinel哨兵搭建的主从架构在高可用上表现又不是很好,尤其是当数据量越来越大,单纯主从结构无法满足对性能的需求时,矛盾便产生了。

随着redis cluster的推出,这种海量数据+高并发+高可用的场景真正从根本上得到了有效的支持。

cluster 模式是redis官方提供的集群模式,使用了Sharding 技术,不仅实现了高可用、读写分离、也实现了真正的分布式存储。

集群内部通信

在redis cluster集群内部通过gossip协议进行通信,集群数据分散的存在于各个节点,通过gossip进行数据的交换。

不同于zookeeper分布式协调中间件,采用集中式的集群数据存储。redis cluster采用分布式的数据管理,优缺点还是比较明显的。在redis中集中式的数据管理类似sentinel主从架构模式。集中式有点在于数据更新实效性更高,但容错性不如分布式管理。gossip协议优点在于大大增强集群容错性。

redis cluster集群中单节点一般配置两个端口,一个端口如6379对外提供api,另一个一般是加1w,比如16379进行节点间的数据交换即用于gossip协议通讯。

gossip协议包含多种消息,如ping pong,meet,fail等。

1.meet:集群中节点通过向新加入节点发送meet消息,将新节点加入集群中。

2.ping:节点间通过ping命令交换数据。

3.pong:响应ping。

4.fail:某个节点主观认为某个节点宕机,会向其他节点发送fail消息,进行客观宕机判定。

分片和寻址算法

hash slot即hash槽。redis cluster采用的正式这种hash槽算法实现的寻址。在redis cluster中固定的存在16384个hash slot。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如上图所示,如果我们有三个节点,每个节点都是一主一从的主从结构。redis cluster初始化时会自动均分给每个节点16384个slot。当增加一个节点4,只需要将原来node1~node3节点部分slot上的数据迁移到节点4即可。在redis cluster中数据迁移并不会阻塞主进程。对性能影响是十分有限的。总结一句话就是hash slot算法有效的减少了当节点发生变化导致的数据漂移带来的性能开销。

集群高可用和主备切换

主观宕机和客观宕机:

某个节点会周期性的向其他节点发送ping消息,当在一定时间内未收到pong消息会主观认为该节点宕机,即主观宕机。然后该节点向其他节点发送fail消息,其他超过半数节点也确认该节点宕机,即客观宕机。十分类似sentinel的sdown和odown。

客观宕机确认后进入主备切换阶段及从节点选举。

节点选举:

检查每个 slave node 与 master node 断开连接的时间,如果超过了 cluster-node-timeout * cluster-slave-validity-factor,那么就没有资格切换成 master。

每个从节点,都根据自己对 master 复制数据的 offset,来设置一个选举时间,offset 越大(复制数据越多)的从节点,选举时间越靠前,优先进行选举。

所有的 master node 开始 slave 选举投票,给要进行选举的 slave 进行投票,如果大部分 master node(N/2 + 1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成 master。

从节点执行主备切换,从节点切换为主节点。

Lettuce的使用

建立连接

使用Lettuce大致分为以下三步:

1.基于Redis连接信息创建RedisClient

2.基于RedisClient创建StatefulRedisConnection

3.从Connection中获取Command,基于Command执行Redis命令操作。

由于Lettuce客户端提供了响应式、同步和异步三种命令,从Connection中获取Command时可以指定命令类型进行获取。

在本地创建Redis Cluster集群,设置主从关系如下:

7003(M) –> 7001(S)

7004(M) –> 7002(S)

7005(M) –> 7000(S)


可以看到成功地获取到了值,由日志可以看出该请求发送到了7004所在的节点上,顺利拿到了对应的值并进行返回。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

作为一个需要长时间保持的客户端,保持其与集群之间连接的稳定性是至关重要的,那么集群在运行过程中会发生哪些特殊情况呢?作为客户端又应该如何应对呢?这就要引出智能客户端(smart client)这个概念了。

智能客户端

在Redis Cluster运行过程中,所有的数据不是永远固定地保存在某一个节点上的,比如遇到cluster扩容、节点宕机、数据迁移等情况时,都会导致集群的拓扑结构发生变化,此时作为客户端需要对这一类情况作出应对,来保证连接的稳定性以及服务的可用性。随着以上问题的出现,smart client这个概念逐渐走到了人们的视野中,智能客户端会在内部维护hash槽与节点的映射关系,大家耳熟能详的Jedis和Lettuce都属于smart client。客户端在发送请求时,会先根据CRC16(key)%16384计算key对应的hash槽,通过映射关系,本地就可实现键到节点的查找,从而保证IO效率的最大化。

但如果出现故障转移或者hash槽迁移时,这个映射关系是如何维护的呢?

客户端重定向

MOVED

当Redis集群发生数据迁移时,当对应的hash槽已经迁移到变的节点时,服务端会返回一个MOVED重定向错误,此时并告诉客户端这个hash槽迁移后的节点IP和端口是多少;客户端在接收到MOVED错误时,会更新本地的映射关系,并重新向新节点发送请求命令。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

ASK

Redis集群支持在线迁移槽(slot)和数据来完成水平伸缩,当slot对应的数据从源节点到目标节点迁移过程中,客户端需要做到智能识别,保证键命令可正常执行。例如当一个slot数据从源节点迁移到目标节点时,期间可能出现一部分数据在源节点,而另一部分在目标节点,如下图所示

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

当出现上述情况时,客户端键命令执行流程将发生变化,如下所示:

1)客户端根据本地slots缓存发送命令到源节点,如果存在键对象则直 接执行并返回结果给客户端

2)如果键对象不存在,则可能存在于目标节点,这时源节点会回复 ASK重定向异常。

3)客户端从ASK重定向异常提取出目标节点信息,发送asking命令到目标节点打开客户端连接标识,再执行键命令。如果存在则执行,不存在则返回不存在信息。

在客户端收到ASK错误时,不会更新本地的映射关系

节点宕机触发主备切换

上文提到,如果redis集群在运行过程中,某个主节点由于某种原因宕机了,此时就会触发集群的节点选举机制,选举其中一个从节点作为新的主节点,进入主备切换,在主备切换期间,新的节点没有被选举出来之前,打到该节点上的请求理论上是无法得到执行的,可能会产生超时错误。在主备切换完成之后,集群拓扑更新完成,此时客户端应该向集群请求新的拓扑结构,并更新至本地的映射表中,以保证后续命令的正确执行。

有意思的是,Jedis在集群主备切换完成之后,是会主动拉取最新的拓扑结构并进行更新的,但是在使用Lettuce时,发现在集群主备切换完成之后,连接并没有恢复,打到该节点上的命令依旧会执行失败导致超时,必须要重启业务程序才能恢复连接。

在使用Lettuce时,如果不进行设置,默认是不会触发拓扑刷新的,因此在主备切换完成后,Lettuce依旧使用本地的映射表,将请求打到已经挂掉的节点上,就会导致持续的命令执行失败的情况。

可以通过以下代码来设置Lettuce的拓扑刷新策略,开启基于事件的自适应拓扑刷新,其中包括了MOVED、 ASK、PERSISTENT_RECONNECTS等触发器,当客户端触发这些事件,并且持续时间超过设定阈值后,触发拓扑刷新,也可以通过enablePeriodicRefresh()设置定时刷新,不过建议这个时间不要太短。


进行以上设置并进行验证,集群在主备切换完成后,客户端在段时间内恢复了连接,能够正常存取数据了。

总结

对于缓存的操作,客户端与集群之间连接的稳定性是保证数据不丢失的关键,Lettuce作为热门的异步客户端,对于集群中产生的一些突发状况是具备处理能力的,只不过在使用的时候需要进行设置。本文目的在于将在开发缓存操作功能时遇到的问题,以及将一些涉及到的底层知识做一下总结,也希望能给大家一些帮助。

star fork

  • 帮助文档: https://gitee.com/yhuse/SunnyUI/wikis/pages
  • Gitee: https://gitee.com/yhuse/SunnyUI
  • GitHub: https://github.com/yhuse/SunnyUI
  • Nuget: https://www.nuget.org/packages/SunnyUI/
  • Blog: https://www.cnblogs.com/yhuse

SunnyUI.Net 是基于.Net Framework 4.0~4.8、.Net 6 框架的 C# WinForm 开源控件库、工具类库、扩展类库、多页面开发框架。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

此版本更新内容为:

+ 增加 * 修改 – 删除

2023-02-07 V3.3.2

+ UIControl: 增加WIN10系统响应触摸屏的按下和弹起事件
* UIDropControl: 下拉框控件增加Tips小红点
* UITextBox: 增加Tips小红点
* UIComboBox: 增加清除按钮
* UIComboTreeView: 下拉框增加显示全选选择框
* UITransfer: 支持鼠标框选和Shift,Ctrl多选移动
* UINavMenu: 修复了鼠标离开事件
* UIIntegerUpDown: 修改文本框数据输入数据变更事件为MouseLeave
* UIDoubleUpDown: 修改文本框数据输入数据变更事件为MouseLeave
* UIFlowLayoutPanel: 增加AutoScroll属性
* UIFlowLayoutPanel: 修复只显示水平滚动条时,鼠标滚轮滚动水平滚动条不动的问题

 

DynamicTp 简介

DynamicTp 是一个基于配置中心实现的轻量级动态线程池监控管理工具,主要功能可以总结为动态调参、通知报警、运行监控、三方包线程池管理等几大类。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

经过多个版本的迭代,目前最新版本 v1.1.0 具有以下特性

  • 代码零侵入:我们改变了线程池以往的使用姿势,所有配置均放在配置中心,服务启动时会从配置中心拉取配置生成线程池对象放到 Spring 容器中,使用时直接从 Spring 容器中获取,对业务代码零侵入

  • 通知告警:提供多种报警维度(配置变更通知、活性报警、容量阈值报警、拒绝触发报警、任务执行或等待超时报警),已支持企业微信、钉钉、飞书、邮件报警,同时提供 SPI 接口可自定义扩展实现

  • 运行监控:定时采集线程池指标数据,支持通过 MicroMeter、JsonLog 日志输出、Endpoint 三种方式,可通过 SPI 接口自定义扩展实现

  • 任务增强:提供任务包装功能,实现 TaskWrapper 接口即可,如 MdcTaskWrapper、TtlTaskWrapper、SwTraceTaskWrapper,可以支持线程池上下文信息传递

  • 多配置中心支持:基于主流配置中心实现线程池参数动态调整,实时生效,已支持 Nacos、Apollo、Zookeeper、Consul、Etcd,同时也提供 SPI 接口可自定义扩展实现

  • 中间件线程池管理:集成管理常用第三方组件的线程池,已集成 Tomcat、Jetty、Undertow、Dubbo、RocketMq、Hystrix、Grpc、Motan、Okhttp3、Brpc、Tars、SofaRpc 等组件的线程池管理(调参、监控报警)

  • 轻量简单:基于 SpringBoot 实现,引入 starter,接入只需简单 4 步就可完成,顺利 3 分钟搞定

  • 多模式:参考 Tomcat 线程池提供了 IO 密集型场景使用的 EagerDtpExecutor 线程池

  • 兼容性:JUC 普通线程池和 Spring 中的 ThreadPoolTaskExecutor 也可以被框架监控,@Bean 定义时加 @DynamicTp 注解即可

  • 可靠性:框架提供的线程池实现 Spring 生命周期方法,可以在 Spring 容器关闭前尽可能多的处理队列中的任务

  • 高可扩展:框架核心功能都提供 SPI 接口供用户自定义个性化实现(配置中心、配置文件解析、通知告警、监控数据采集、任务包装等等)

  • 线上大规模应用:参考美团线程池实践,美团内部已经有该理论成熟的应用经验

技术架构

v1.1.0 发布记录

Features

  • adapter 模块新增 motan rpc 框架线程池管理

  • adapter 模块新增 okhttp3 线程池管理

  • 新增 OrderedDtpExecutor,感谢 @hailang 提供实现

  • adapter 模块新增 brpc(starlight) 线程池管理

  • adapter 模块新增 tars rpc 线程池管理

  • 线程池配置添加 notifyEnabled 字段,可以全局控制通知功能开启与否

  • 新增 StreamRocketMqDtpAdapter,Rocketmq 线程池管理支持 Stream 场景下使用,感谢 @MIEAPP 提供实现

  • adapter 模块新增 sofa-rpc 框架线程池管理

  • 通过 SpringExecutor 支持 Spring 线程池

  • 支持飞书验签,感谢@ZhaoGZ 提供实现

BugFix

  • ApacheDubbo 线程池初始化失败问题修复,感谢 @hdgaadd 提供实现

  • SimpleTpProperties keepAliveTime 字段数据类型错误问题修复

Optimize

  • 要修改的核心线程数大于当前最大线程数不能修改问题优化

  • 引入 commons-collections,优化 hutool 高低版本不兼容问题

  • notify 模块相关代码重构

  • 采用 checkstyle 调整代码风格

项目地址

目前累计 3.2k star,感谢你的 star,欢迎 pr,业务之余一起给开源贡献一份力量

官网:https://dynamictp.cn

gitee 地址:https://gitee.com/dromara/dynamic-tp

github 地址:https://github.com/dromara/dynamic-tp

一直以来,在众多Kubernetes开源管理平台选项中,Rancher深受社区用户的青睐。 SUSE在确保开源产品持续灵活演进的同时,也致力于满足企业用户的使用场景,为此SUSE正式推出Rancher Prime。Rancher Prime是Rancher的一种分发版,核心功能代码均来自Rancher社区版,但更加重视安全方面的建设,并面向企业用户强化了相关功能和服务。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Rancher Prime为企业用户提供可信的镜像仓库,以获取核心安装介质。SUSE不仅优化加速了国内的下载链路,还将持续治理各个依赖组件镜像的CVE,从容器镜像角度提升软件供应链安全。这得益于SUSE在Linux和容器领域长期的工程化积累,几乎所有的Rancher Prime组件都基于SUSE BCI(Base Container Image)进行构建。BCI提供了标准的Linux Container Image和Language Container Image,并在镜像源头进行安全治理。在容器运行时方面,更有SUSE NeuVector进行产品级的整合,进一步提升Rancher Prime的综合安全能力。

 

Rancher Prime引入了UI Extension功能,提供了灵活的UI扩展方式。企业用户通常会有一些UI扩展需求,但又不希望影响其跟随Rancher主线版本进行演进,UI Extension机制可以很好地解决这一问题。 用户可以更新Extension的版本,并应用在不同阶段的Rancher Prime版本上,让Kubernetes管理平台和其他内部服务更好地融合,统一核心功能与扩展功能的操作体验。

 

SUSE中国一直奉行产品本地化的治理原则,面向国内企业的应用场景,Rancher Prime也更具优势。不仅增加了高性能容器网络、审计日志、GPU管理、Harbor对接等功能,在生态兼容方面也有很多增强。

 

对Native Cloud的支持。海外用户主要聚焦于AWS、Azure、GCP的整合使用,而Rancher Prime除了扩展这些公有云的中国区域支持外,还会额外对阿里云、腾讯云以及华为云进行支持。这并非简单的导入管理,而是对公有云托管集群的全生命周期支持。用户可以在Rancher Prime的UI上,统一管理来自不同云厂商的Kubernetes,包括集群的创建和销毁,以及节点组编辑和集群升级等操作。

 

对国产OS的支持。SUSE中国团队与欧拉开源社区建立了长期合作关系,并积极进行产品落地。在操作系统的支持矩阵上,Rancher Prime 引入了对openEuler Linux的支持,并将其列入长期支持列表中。Rancher Prime 2.7已完成了对openEuler 22.03和22.03 SP1版本的验证。

 

对ARM体系的支持。ARM在全球的部署比例正在攀升,公有云的ARM化趋势非常明显,这些变化逐步推动企业的部署环境向ARM转变。Rancher Prime 已经将 ARM适配作为持续工程化的一部分,并对国内主流ARM平台进行兼容,包括Kunpeng、Yitian、Ampera等处理器。

漏洞描述

Kafka 是 Apache 软件基金会的一种分布式的、基于发布/订阅的消息系统,可以处理消费者在网站中的所有动作流数据。Kafka Connect 是一种工具,用于在 Apache Kafka 和其他数据系统之间以可扩展且可靠的方式传输数据。

Kafka 2.3.0 至 3.3.2 版本中,具有 Kafka Connect worker 访问权限且可以使用任意 Kafka 客户端 SASL JAAS 配置和基于 SASL 的安全协议创建/修改连接器的攻击者可通过将连接器的任何 Kafka 客户端的 属性设置为“com.sun.security.auth.module.JndiLoginModule”,此操作可通过“producer.override.sasl.jaas.config”、“consumer.override.sasl.jaas.config”或“admin.override.sasl.jaas.config”属性完成。

攻击者可利用此漏洞将服务器连接到可控的 LDAP 服务器并反序列化恶意 LDAP 响应,进而远程执行恶意代码或造成拒绝服务。

漏洞名称 Apache Kafka Connect 模块存在反序列化漏洞 漏洞类型 反序列化 发现时间 2023-02-08 漏洞影响广度 广 MPS编号 MPS-2023-3834 CVE编号 CVE-2023-25194 CNVD编号 –

影响范围

org.apache.kafka:kafka@[2.3.0, 3.4.0)

修复方案

将组件 org.apache.kafka:kafka 升级至 3.4.0 及以上版本

参考链接

https://www.oscs1024.com/hd/MPS-2023-3834

https://nvd.nist.gov/vuln/detail/CVE-2023-25194

https://kafka.apache.org/cve-list

https://hackerone.com/reports/

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

漏洞描述

OpenSSL 是一个用于加密和安全通信的开源工具包。

受影响版本的 OpenSSL 的 X.509 GeneralName 中存在 X.400 地址类型混淆漏洞。漏洞源于 X.400 地址被解析为 ASN1_STRING,但 GENERAL_NAME 的 public structure 错误地将 x400 Address 字段的类型指定为 ASN1_type,并且 OpenSSL 的 GENERAL_NAME_cmp 函数将此字段解释为 ASN1_TYPE ,而不是 ASN1_STRING。当 OpenSSL 启用 CRL checking 时(即应用程序设置 X509_V_FLAG_RL_CHECK 标志),攻击者向 memcmp 调用传递任意指针,进而读取内存或造成拒绝服务。

漏洞名称 OpenSSL 存在拒绝服务漏洞(类型混淆) 漏洞类型 不正确的类型转换 发现时间 2023-02-08 漏洞影响广度 一般 MPS编号 MPS-2023-1620 CVE编号 CVE-2023-0286 CNVD编号 –

影响范围

OpenSSL@[3.0, 3.0.8)

OpenSSL@[1.1.1, 1.1.1t)

OpenSSL@[1.0.2, 1.0.2zg)

修复方案

升级OpenSSL到 1.0.2zg 或 1.1.1t 或 3.0.8 或更高版本

参考链接

https://www.oscs1024.com/hd/MPS-2023-1620

https://nvd.nist.gov/vuln/detail/CVE-2023-0286

https://www.openssl.org/news/secadv/.txt

https://github.com/openssl/openssl/commit/2fe0ef79dbc51ca0cad658

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

兆芯和海光作为openKylin(开放麒麟)社区共建伙伴,在加入社区Kernel SIG后便开展了深入技术对接,并于近期正式完成openKylin操作系统兆芯KX-U6780A,兆芯KX-6000G海光Hygon 3350等三款国产X86平台的适配测试工作,其适配相关成果后续也将逐步合并到openKylin版本中。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

 

测试期间,openKylin操作系统在以上三款国产X86平台上整体运行稳定,功能、性能及兼容性方面表现良好。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

开先® KX-6000系列KX-U6780A型号处理器

成功适配openKylin操作系统

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

开先® KX-6000G系列处理器

成功适配openKylin操作系统

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Hygon 3350处理器

成功适配openKylin操作系统

  • 开先® KX-6000系列CPU核心采用超标量、多发射、乱序执行架构设计,兼容最新的x86指令集,可支持64位系统,以及 CPU 硬件虚拟化技术。同时支持SM3/SM4国密算法,可提供基于硬件的数据加密保护,满足多种市场的应用需求,主要面向高性能桌面、便携终端、嵌入式等市场应用领域。
  • 兆芯新一代开先® KX-6000G系列处理器,集成处理器核心、双通道DDR4内存控制器、高性能3D图形加速引擎、高清流媒体解码器与显示接口以及PCIe 3.0 、SATA、USB等高速IO接口,可以支持单芯片解决方案。非常适合一体机、笔记本、便携式终端以及物联网计算平台等兼顾高性能、低功耗需求的应用领域。
  • 海光3000系列处理器集成4-8核心,具有超线程特性,支持8-16线程,支持32路PCle通道,2个DDR4内存通道,单核最高加速频率达到3.3GHz;3000系列处理器满足可信计算、隐私计算等安全领域特性,芯片支持SM2/SM3/SM4国密算法,并提供硬件加速功能,3000系列芯片主要应用于入门级服务器、工作站、工业控制等市场,满足党政企业及关基行业的办公业务场景,基于海光终端处理器,海光也为各企业和专业人员提供高效解决方案。

未来openKylin社区将持续与兆芯、海光开展深入合作,不断优化和完善openKylin操作系统在国产X86平台上的应用体验,共同推动国产桌面操作系统的普及和国产开源生态的打造,推动openKylin国产化生态布局进一步完善。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

openKylin(开放麒麟)社区旨在以“共创”为核心,在开源、自愿、平等、协作的基础上,通过开源、开放的方式与企业构建合作伙伴生态体系,共同打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态繁荣发展。

社区首批理事成员单位包括麒麟软件、普华基础软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、心科技、中国电科32所、技德系统、北京麟卓、先进操作系统创新中心等13家产业同仁和行业机构。

近日,OSCHINA 和 Gitee 联合发布了《2022 中国开源开发者报告》。该报告由” 前沿开源技术领域解读 “ ” 中国开源创业观察 2022“,以及” 开发者画像分析 “ 三个章节组成。其中,Cocos 引擎技术总监凌华彬在报告中对开源大前端领域进行了解读,以下为原文。


WebGPU 毫无疑问会在未来取代 WebGL

Web 一直是最开放和易于传播的平台,而今天游戏、宇宙等数字内容非常依赖 Web 平台的各种特性,但是 Web 环境中还没有跟上 DirectX12、Vulkan、Metal 等现代图形接口的变革。这一现状随着 WebGPU 标准的逐步完善,即将得到改变。这会给 Web 端带来非常振奋人心的未来可能性。

WebGPU 是由 W3C GPU for the Web 社区组所发布的规范,目标是允许网页代码以高性能且安全可靠的方式访问 GPU 功能。WebGPU 是一套为浏览器设计的次时代图形 API 标准,为了弥合各个平台图形 API 的差异性,它对 DirectX12、Vulkan、Metal 进行了融合和封装。借助 WebGPU,可以充分释放现代 GPU 硬件的强大能力,让开发者可以用 TS/JS 在 Web 端也开发媲美原生表现力的场景,实现更大型更复杂的 3D 场景表现,甚至使用现代 GPU 的通用计算能力完成之前无法想像的复杂计算任务。

自 2018 年起,Google Chrome 团队就已经宣布着手 WebGPU 标准的实现工作。时至今日,WebGPU 的各类接口、生态、应用已日趋完善,WebGPU 1.0 或将于 2023 年初正式推出。而就在 2022 年 11 月,商用开源3D引擎 Cocos 发布了支持 WebGPU 的新版本 Cocos Creator 3.6.2,为国内首个支持该渲染后端的开源引擎。

作为 Google、Apple、Mozilla 等浏览器厂商共同推进的次时代图形标准,WebGPU 毫无疑问会在未来取代 WebGL,这也是 Cocos 投资 WebGPU 技术的核心原因。目前 WebGPU 仍然在草案阶段,不过已经锁定了 v1.0 的目标,确保至少一家浏览器厂商完成全部 feature 的实现,正在全力推进中,预计很快就会完成 v1.0 里程碑。而且 Chromium、Safari、Firefox 等浏览器都已经开始推进实验性实现,其中 Cocos 的 WebGPU 发布在 Chromium 中已经得到验证。

从时间上来看,WebGPU 的出现时间稍晚,但也正因如此,让 WebGPU 得以借助次时代图形 API 的经验,做出更好的设计。未来随着 WebGPU 标准在主流浏览器的逐步落地,其能力将给 H5、小程序等的内容创作与性能表现带来更多可能,也一定会在 Web 平台出现不逊于原生 app 的图形渲染效果,同时基于 Web 端的优势给用户带来更轻量和便捷的体验。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
凌华彬

Cocos 引擎技术总监。法国里尔科技大学图像、视觉与交互专业硕士。2011 年开始投入在 Web 渲染引擎和交互内容研发。2014 年加入 Cocos 团队负责 Cocos2d-html5 Web 引擎的研发。从 2017 年开始专注于 Cocos Creator 的 3D 引擎研发,推动了 Cocos Creator 的渲染器重构、原生渲染器和 3D 化进程,对引擎架构、多后端渲染技术、跨平台框架都有非常深入的理解。目前正带领团队基于现代图形 API:WebGPU、Vulkan、Metal 打造国人自己的跨平台商业化 3D 引擎。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布) 

在 “前沿开源技术领域解读” 部分,除了凌华彬之外, 还有多位在其领域有所建树的一线开发者和开源商业化公司创始人,对目前国内外流行的前沿开源技术领域过去的发展和未来的趋势进行了深入的洞察,覆盖开源云原生、开源 AI、开源大前端、开源大数据、开源 DevOps、RISC-V、开源操作系统、开源数据库、编程语言九大领域。

《2022中国开源开发者报告》官网地址:https://gitee.com/report/china-open-source-2022/

这篇文章本来要在年前和小伙伴们见面,但是因为我之前的 Mac 系统版本是 10.13.6,这个版本比较老,时至今天在运行一些新鲜玩意的时候有时候会有一些 BUG(例如运行最新版的 Nacos 等),运行 gRPC 的插件也有 BUG,代码总是生成有问题,但是因为系统升级是一个大事,所以一直等到过年放假,在家才慢慢折腾将 Mac 升级到目前的 13.1 版本,之前这些问题现在都没有了,gRPC 的案例现在也可以顺利跑起来了。

所以今天就来和小伙伴们简单聊一聊 gRPC。

1. 缘起

我为什么想写一篇 gRPC 的文章呢?其实本来我是想和小伙伴们梳理一下在微服务中都有哪些跨进城调用的方式,在梳理的过程中想到了 gRPC,发现还没写文章和小伙伴们聊过 gRPC,因此打算先来几篇文章和小伙伴们详细介绍一下 gRPC,然后再梳理微服务中的跨进程方案。

2. 什么是 gRPC

了解 gRPC 之前先来看看什么是 RPC。

RPC 全称是 Remote Procedure Call,中文一般译作远程过程调用。RPC 是一种进程间的通信模式,程序分布在不同的地址空间里。简单来说,就是两个进程之间互相调用的一种方式。

gRPC 则是一个由 Google 发起的开源的 RPC 框架,它是一个高性能远程过程调用 (RPC) 框架,可以在任何环境中运行。gRPC 通过对负载均衡、跟踪、健康检查和身份验证的可插拔支持,有效地连接数据中心内和数据中心之间的服务。

在 gRPC 中,客户端应用程序可以直接调用部署在不同机器上的服务端应用程序中的方法,就好像它是本地对象一样,使用 gRPC 可以更容易地创建分布式应用程序和服务。与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定基于参数和返回类型远程调用的方法。在服务端侧,服务端实现接口,运行 gRPC 服务,处理客户端调用。在客户端侧,客户端拥有存根(Stub,在某些语言中称为客户端),它提供与服务端相同的方法。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

gRPC 客户端和服务端可以在各种环境中运行和相互通信 – 从 Google 内部的服务器到你自己的桌面 – 并且可以使用 gRPC 支持的任何语言编写。因此,你可以轻松地用 Java 创建 gRPC 服务端,使用 Go、Python 或 Ruby 创建客户端。此外,最新的 Google API 将包含 gRPC 版本的接口,使你轻松地将 Google 功能构建到你的应用程序中。

gRPC 支持的语言版本:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

说了这么多,还是得整两个小案例小伙伴们可能才会清晰,所以我们也不废话了,上案例。

3. 实践

先来看下我们的项目结构:


大家看下,这里首先有一个 grpc-api,这个模块用来放我们的公共代码;grpc-server 是我们的服务端,grpc-client 则是我们的客户端,这些都是普通的 maven 项目。

3.1 grpc-api

在 grpc-api 中,我们首先引入项目依赖,如下:


除了这些常规的依赖之外,还需要一个插件:


我来说一下这个插件的作用。

默认情况下,gRPC 使用 Protocol Buffers,这是 Google 提供的一个成熟的开源的跨平台的序列化数据结构的协议,我们编写对应的 proto 文件,通过上面这个插件可以将我们编写的 proto 文件自动转为对应的 Java 类。

> 多说一句,使用 Protocol Buffers 并不是必须的,也可以使用 JSON 等,但是目前来说这个场景更常用的还是 Portal Buffers。

接下来我们在 main 目录下新建 proto 文件夹,如下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

注意,这个文件夹位置是默认的。如果我们的 proto 文件不是放在 src/main/proto 位置,那么在配置插件的时候需要指定 proto 文件的位置,咱们本篇文章主要是入门,我这里就使用默认的位置。

在 proto 文件夹中,我们新建一个 product.proto 文件,内容如下:


这段配置算是一个比较核心的配置了,这里主要说明了负责进程传输的类、方法等到底是个啥样子:

  1. :这个是 protocol buffers 的版本。
  2. :这个字段是可选的,如果设置为 true,表示每一个 message 文件都会有一个单独的 class 文件;否则,message 全部定义在 outerclass 文件里。
  3. :这个字段是可选的,用于标识生成的 java 文件的 package。如果没有指定,则使用 proto 里定义的 package,如果package 也没有指定,那就会生成在根目录下。
  4. :这个字段是可选的,用于指定 proto 文件生成的 java 类的 outerclass 类名。什么是 outerclass?简单来说就是用一个 class 文件来定义所有的 message 对应的 Java 类,这个 class 就是 outerclass;如果没有指定,默认是 proto 文件的驼峰式;
  5. :这个属性用来定义 message 的包名。包名的含义与平台语言无关,这个 package 仅仅被用在 proto 文件中用于区分同名的 message 类型。可以理解为 message 全名的前缀,和 message 名称合起来唯一标识一个 message 类型。当我们在 proto 文件中导入其他 proto 文件的 message,需要加上 package 前缀才行。所以包名是用来唯一标识 message 的。
  6. :我们定义的跨平台方法都写在 service 中,上面的案例中我们定义了两个方法:addProduct 表示添加一件商品,参数是一个 Product 对象,返回值则是刚刚添加成功的商品的 ID;getProduct 则表示根据 ID 查询一个商品,参数是一个商品 ID,返回值则是查询到的商品对象。这里的定义相当于一个接口,将来我们要在 Java 代码中实现这个接口。
  7. :这里有点像我们在 Java 中定义类,上文中我们定义了两个类,分别是 Product 和 ProductId 两个类。这两个类在 service 中被使用。

message 中定义的有点像我们 Java 中定义的类,但是不能直接使用 Java 中的数据类型,毕竟这是 Protocol buffers,这个是和语言无关的,将来可以据此生成不同语言的代码,这里我们可以使用的类型和我们 Java 类型之间的对应关系如下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

另外我们在 message 中定义的属性的时候,都会给一个数字,例如 id=1,name=2 等,这个数字将来会在二进制消息中标识我们的字段,并且一旦我们的消息类型被使用就不应更改,这个有点像序列化的感觉。

实际上,这个 message 编译后的字节内容大概像下面这样:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这里的标签中的内容包含两部分,字段索引和字段类型,字段索引其实就是我们上面定义的数字。

定义完成之后,接下来我们就需要使用插件来生成对应的 Java 代码了,插件我们在前面已经引入了,现在只需要执行了,如下图:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

注意,compile 和 compile-custom 两个指令都需要执行。其中 compile 用来编译消息对象,compile-custom 则依赖消息对象,生成接口服务。

首先我们 compile 看看生成的代码,如下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

再看 compile-custom 生成的代码,如下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

好了,这样我们的准备工作就算完成了。

> 有的小伙伴生成的代码文件夹颜色不对劲,此时有两种解决办法:1.选中目标文件夹,右键单击,选择 Mark Directory as-> Generated Sources root;2.选中工程,右键单击,选择 Maven->Reload project。推荐使用第二种方案。

3.2 grpc-server

接下来我们创建 grpc-server 项目,并使该项目依赖 grpc-api,然后在 grpc-server 中,提供 ProductInfo 的具体实现:


是根据我们在 proto 文件中定义的 service 自动生成的,我们的 ProductInfoImpl 继承自该类,并且提供了我们给出的方法的具体实现。

以 addProduct 方法为例,参数 request 就是将来客户端调用的时候传来的 Product 对象,返回结果则通过 responseObserver 来完成。我们的方法逻辑很简单,我就把参数传来的 Product 对象打印出来,然后构建一个 ProductId 对象并返回,最后调用 表示数据返回完毕。

剩下的 getProduct 方法逻辑就很好懂了,我这里就不再赘述了。

最后,我们再把这个 grpc-server 项目启动起来:


由于我们这里是一个 JavaSE 项目,为了避免项目启动之后就停止,我们这里调用了 方法,就是让服务启动成功之后不要停止。

3.3 grpc-client

最后再来看看客户端的调用。首先 grpc-client 项目也是需要依赖 grpc-api 的,然后直接进行方法调用,如下:


小伙伴们看到,这里首先需要和服务端建立连接,给出服务端的地址和端口号即可,usePlaintext() 方法表示不使用 TLS 对连接进行加密(默认情况下会使用 TLS 对连接进行加密),生产环境建议使用加密连接。

剩下的代码就比较好懂了,创建 Product 对象,调用 addProduct 方法进行添加;创建 ProductId 对象,调用 getProduct。Product 对象和 ProductId 对象都是根据我们在 proto 中定义的 message 自动生成的。

4. 总结

好啦,一个简单的例子,小伙伴们先对 gRPC 入个门,后面松哥会再整几篇文章跟大家介绍这里边的一些细节。</product></productid>

1.前言

1.1 社区数字场景

社区业务有非常多的数字统计场景,基础的场景主要有以下这些:

  • 用户维度:发布内容数、被点赞数、被收藏数、关注数、粉丝数、点赞内容数、收藏内容数等。

  • 内容维度:内容点赞数、内容阅读数、内容分享数、内容收藏数、内容评论数等。

  • 标签维度:话题内容数、特效内容数、商品内容数、品牌内容数等。

其中部分场景还会有很多细分情况,例如内容相关的统计还会有以下场景:

  • 根据内容类型统计:图文数、视频数、专栏数等。

这样排列组合出来的最终结果就有很多了,比如需要查询用户发布的图文内容数、用户点赞的视频内容数等等,且这些数字一般都需要能够支持高度精确性、高性能查询和批量查询等能力。

1.2 具体案例

具体案例可参考下列图示:

  • 图1. 个人主页展示获赞与收藏总数、粉丝数、关注数、发布动态数(视频数、穿搭数、专栏数)。

1.jpeg

  • 图2. 他人主页展示获赞与收藏总数、粉丝数、关注数、点赞动态数(视频数、专栏数)。

2.png

  • 图3. 话题主页展示话题内容数。

3.png

2.逐渐浮现的系统风险

2.1 历史方案

早期社区是直接采用Count数据表+缓存的方式,这种方式在体量较小和单体服务的情况下完全没问题,而且成本低、性能高、绝对精准,但随着社区的体量逐渐变大、微服务拆分越来越细之后,该方案就会越来越难以支撑业务。

2.2 系统风险

性能瓶颈和稳定性风险:

一方面业务明细表的体量越来越大,需要通过分库分表来解决问题,分库分表后再用Count聚合的方式性能就会变差。

另一方面业务统计规则越来越复杂,使用数据库Count的方式会使数据查询语句越来越复杂,容易引发慢SQL从而导致数据库不稳定。

计数业务数据层和缓存都和核心业务部分放在一起,若出现统计导致的不稳定会影响核心业务场景的使用,从而将小问题变成大问题。

缓存策略问题:

热点穿透问题:部分计数场景下是有新数据就删除缓存的策略,但若出现热点内容、热点用户时,对应的统计数据(如点赞数、粉丝数)会频繁删除缓存导致穿透的问题,且一般热点内容和用户产生的数据量比较大、查询量也比较大,会更容易加剧问题从而引发雪崩。

数据一致性问题:部分计数场景下是定时更新缓存的策略,缓存操作和MySQL操作无法在一个事务中完成,会产生不一致的问题,且在越频繁变更的场景下差异值就会越大。

3

计数系统设计与实现

结合当前社区的业务现状、体量以及考虑中长期体量增长的规划,我们也调研了业内比较常见的一些实现方案,最终敲定通过维护一套计数中心的服务,由计数中心服务统一管理社区的数字统计的方式,整体情况大致如下:

4.jpeg

3.1 写场景

该场景下计数中心内部主要干三件事,主要包括数据获取、数据处理、数据持久化。

3.1.1 数据获取

数据的获取一般有两种方式,通过接口或通过MQ的方式,既然是平台服务更希望对业务没什么侵入性,因此我们目前采用的主要是MQ的方式。

使用MQ的情况下也有两种方案可取,一种是业务服务根据事件触发MQ消息,需要业务服务先保证业务数据已经持久化且需要生产端保证消息投递无丢失,另一种则是直接通过订阅业务数据表binlog的方式,这种方式可以保证业务数据已经持久化,目前得物已有DTS(数据订阅平台),使用起来也比较方便且可保证消息投递不丢失,因此我们目前更多的是采用第二种方案。

数据获取到后我们做一些格基础校验,验证是否存在我们必要的一些字段是否完整,同时需要验证数据处理的幂等性防止数据重复消费等,通过消息ID和业务唯一ID做幂等,然后把每行业务数据的各字段格式化成变更前和变更后俩个值且可以区分出是新增还是更新(binlog消息体就是这样因此更加方便),之后就可以进入数据处理阶段。

3.1.2 数据处理

拿到通过校验和格式化后的数据,根据对应的事件和规则来判断当前变更数据具体要做什么操作,我们通过具体的案例来看会更直观,如:

场景1. 用户A关注用户B

第一步,判断出该场景下需要变更的统计数,用户A的关注数要+1,用户B的粉丝数要+1。

第二步,提取需要变更的统计数的对象值,如用户A的ID和用户B的ID。

第三步,格式化成统计的格式,对象ID+统计类型+统计数变化值。

第四步,调用数据持久化的方法。

场景2. 用户A发布的图文内容状态由正常变为删除

第一步,判断出该场景下需要变更的统计数,用户A发布的图文内容数要-1。

第二步,提取需要变更的统计数的对象值,如用户A的ID。

第三步,格式化成统计的格式,对象ID+统计类型+统计数变化值。

第四步,调用数据持久化的方法。

3.1.3 数据持久化

持久化部分主要分为两块,一是DB持久化,二是对于缓存的更新。社区的数字统计场景主要有以下两种情况:

只增不减:如内容分享事件,每次事件触发只需要给内容的分享数+1即可。

既有增又有减:如用户A(关注/取消关注)用户B事件,需要给用户A关注数(+1/-1),也需要给用户B的粉丝数(+1/-1)。

又因为我们通过MQ消费数据是无序的,极端情况下可能会出现先减再加的情况从而导致负数的出现,因此存储层的字段需要支持有符号的数据,保证最终计算的结果是正确的即可。DB层持久完成后再直接操作缓存变更数字并延长有效期,若缓存不存在则不处理等待读场景有需要时再处理。

3.2 读场景

读场景整体逻辑比较简洁,就是先查缓存,缓存不存在就查询DB再写入缓存即可,可批量跨场景查询,需要注意对负数情况的处理。

4.总结及规划

4.1 总结

计数中心是业内比较常见的做法,相对于老方案能够降低各个业务对于复杂计数场景的维护成本,提升迭代效率和系统稳定性,独立出来后在出现异常时业务也可做短时间降级,从而降低对核心业务的影响面。

4.2 规划

目前社区已有多个场景接入计数中心,结合当前的现状及未来的可能性,考虑后续主要优化方向主要有:

11111.jpg

文/小夏

#01 LVGL简介

1.png
实用自行车码表

9.png
具有科技感的奖杯

实现这些DIY作品的背后,都有同样一个功能强大的GUI——LVGL。

LVGL的作者是来自匈牙利的Gabor Kiss-Vamosikisvegabor,LVGL用C语言编写,以实现最大的兼容性(与C ++兼容),模拟器可在没有嵌入式硬件的PC上启动嵌入式GUI设计,同时LVGL作为一个图形库,它自带着接近三十多种小工具可以供开发者使用。这些强大的构建块按钮搭配上带有非常丝滑的动画以及可以做到平滑滚动的高级图形,同时兼具着不高的配置要求以及开源属性,显著的优势使得LVGL蔚然成风,成为广大开发者在选择GUI时的第一选择。

20190824152251444.gif

-主要特性-

  • 强大的构建块,如按钮,图表,列表,滑块,图像等。
  • 高级图形动画,抗锯齿,不透明度,平滑滚动
  • 各种输入设备,如触摸板、鼠标、键盘、编码器等
  • 多语言支持与UTF-8编码
  • 多显示器支持,即使用更多的TFT,单色显示器同时
  • 完全可定制的图形素与css类样式
  • 硬件独立与任何微控制器或显示器使用
  • 可扩展,使用少量内存(64kb Flash, 16kb RAM)
  • 支持操作系统、外部内存和GPU,但不是必需的
  • 单帧缓冲操作,甚至与高级图形效果
  • 用C编写的最大兼容性(c++兼容)
  • 模拟器在没有嵌入式硬件的PC上开始嵌入式GUI设计
  • 绑定到MicroPython
  • 教程,例子,快速GUI设计的主题
  • 文档可以在线和PDF格式获取
  • 麻省理工学院许可下的免费和开源

图片1.png

-配置要求-

  • 基本上,每个能够驱动显示器的现代控制器都适合运行 LVGL。最低要求是:16、32 或 64 位微控制器或处理器
  • 建议使用 16 MHz 时钟速度
  • 闪存/ROM:> 64 kB 用于非常重要的组件 (> 建议使用 180 kB)
    RAM:静态 RAM 使用量:0~2 kB,取决于使用的功能和对象类型
    堆: > 2kB (> 建议使用 8 kB)
    动态数据(堆): > 2 KB (> 如果使用多个对象,建议使用 16 kB). 在 lv_conf.h 文件中配置 LV_MEM_SIZE 生效。
    显示缓冲区:> “水平分辨率”像素(推荐> 10 × 10ד水平分辨率”)
    MCU 或外部显示控制器中的一个帧缓冲器
  • C99 或更新的编译器
  • 具备基本的 C(或 C++)知识

一块能驱动显示屏且Flash大于64KB,RAM大于20KB的单片机都可以支持运行LVGL。这样也就说明只需要是我们经常用于开发的单片机几乎都可以支持(16bit及以上)LVGL,LVGL能够同时被这么多平台支持的主要原因是LVGL对硬件的要求并不算太高。

-系统框架-

LVGL本身是一个图形库。

我们的应用程序通过调用LVGL库来创建GUI。它包含一个HAL(硬件抽象层)接口,用于注册显示和输入设备驱动程序。驱动程序除特定的驱动程序外,它还有其他的功能,可驱动显示器GPU、读取触摸板或按钮的输入。

MCU有两种典型的硬件设置。一个带有内置LCD/TFT驱动器的外围设备,而另一种是没有内置LCD/TFT驱动器的外围设备。相同的是,这两种情况都需要一个帧缓冲区来存储屏幕的当前图像。

集成了TFT/LCD驱动器的MCU如果MCU集成了TFT/LCD驱动器外围设备,则可以直接通过RGB接口连接显示器。在这种情况下,帧缓冲区可以位于内部RAM(如果MCU有足够的RAM)中,也可以位于外部RAM(如果MCU具有存储器接口)中。

如果MCU没有集成TFT/LCD驱动程序接口,则必须使用外部显示控制器(例如SSD1963、SSD1306、ILI9341 )。在这种情况下,MCU可以通过并行端口,SPI或通过I2C与显示控制器进行通信。帧缓冲区通常位于显示控制器中,从而为MCU节省了大量RAM。

#02 常见GUI对比

早些年间大部分MCU的资源和处理能力有限,受制于资源以及处理能力的不足,很少有基于MCU通用的GUI。

现如今,随着MCU技术的发展,MCU性能以及属性有了很大改变,相较从前,现在MCU资源增加,处理能力增强,市场需求增长,GUI的功能自然也越来越丰富了。

-LVGL-

LVGL集成了占用小、多平台使用、移植简单、操作简单、开源免费等一系列特点。对于使用者来说,LVGL拥有30多个可以随时使用的小部件的同时,甚至还可以自定义控件。

LVGL经常被使用在MCU级别的设备上,因其可以在多平台上移植使用以及在不同显示器上,以C编写,对于资源紧张的MCU来说十分适合。

图片5.png

-MiniGUI-

MiniGUI 是一款面向嵌入式系统的高级窗口系统和图形用户界面支持系统,遵循GPL协议。作为操作系统和应用程序之间的一个中间件,MiniGUI 将底层操作系统和硬件平台的细节隐藏起来,并为上层的应用程序提供了一致接口。

MiniGUI同时具有多种技术特性,包括可在含有MMU的32位处理器架构之上运行;同时支持低端、高端显示设备以及具备副屏支持的功能;方便为不同操作系统和环境应运而生的三种运行模式以及内建资源的支持;嵌入式应用程序开发和调试的跨操作系统支持的属性;完备的多窗口机制和消息传递机制。

3.jpg

  • 优点

    支持多种嵌入式操作系统,可移植性强;
    可伸缩的系统架构,易于扩展;
    功能丰富,可灵活剪裁;
    轻型,资源占用少;
    高性能,高可靠性。

  • 缺点

    对图形设备的抽象层次太高。

-Qt(Qt for MCUs)-

Qt for MCUs是一个完整的图形框架和工具包,包含在微控制器上设置、开发和部署GUI所需要的一切。您可以在裸机或实时操作系统上运行应用程序。

Qt for MCUs带有三样开发工具,包括一个配备了完善的代码编辑器、版本控制等功能的IDE(Qt Creator);以Qt QML语言编写的帮助从头开始或基于咸亨UI空间快速设计和构建应用程序的组件WYS|WYG编辑器(Qt Quick Designer);Qt Quick Ultralite 图形框架提供了丰富的 QML API 集,用于构建流畅的 GUI 和渲染引擎。

4.png

  • 优点

    复用您在微控制器上的现有技能;
    通过跨设备(从高端到大众设备)的技术一致性,来降低维护成本;
    在不影响图形性能的前提下,向微控制器演进以降低硬件成本;
    将传统解决方案升级到现代的跨平台图形工具包。

-emWin-

emWin支持在任何嵌入式系统上创建高效、高质量的图形用户界面,emWin支持资源受限的微控制器的系统,运行令人惊叹的交互界面。

emWin与单任务和多任务环境兼容,可以使用专有的操作系统,也可以与任何商业RTOS兼容。它以C语言源代码提供,使其成为嵌入式市场的专业、通用GUI,可用于多种不同的场景。

5.png

  • 优点

    创建惊人的图形与功能强大,易于使用的API
    适用于任何显示器和微控制器
    适用于任何ANSI C/C++开发环境
    体验可靠的图形解决方案
    嵌入式图形用户界面解决方案

最后上一张对比图,更直观!

6.png

#03 D1哪吒 & LVGL

轻量 的属性给LVGL带来了无数粉丝,在使用各种低配置的小型开发板时,大部分开发者都会第一时间想到LVGL,这同时又突出展现出了它的另一个特点 易移植 

同样是开源、精简、轻量级,RISC-V和LVGL在设计理念上简直不谋而合,他们或许就代表着未来十年科技发展的主流。

在全志在线社区论坛上,有小伙伴发布了一篇将LVGL移植到哪吒D1上的帖子,一时也是引起广泛讨论

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

原帖&效果视频见链接:

哪吒D1开发板 LVGL7 源码下载(带git仓库)bbs.aw-ol.com/topic/303/
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
 

视频中使用的是D1哪吒开发板,配上一块带触摸的7寸MIPI屏幕。可以看到移植的LVGL DEMO在RISC-V指令集的芯片上丝滑运行,毫无压力。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

原帖&效果视频见链接:

【DIY教程】D1的双屏异显第一弹来啦!D1同时支持两个屏幕,一共做UI交互,一边个播放视频bbs.aw-ol.com/topic/362/
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

借助芯片的双屏异显功能,D1可以一边用LVGL做UI交互,另一边又在解码播放视频,很好的解决追剧星人在追剧时候就难以同时操作的问题,不会占用HDMI屏幕输出需要太多资源的同时,LVGL也很好的帮助了屏幕内容在mipi上的丝滑输出,成功实现双屏异显。

而要在哪吒上把LVGL玩起来也非常简单,只需要下载源码后使用编译命令编译源码:

 

然后使用Tina Linux自带的adb 将demo推到开发板里,就可以玩起来了。如果没有MIPI屏幕,使用HDMI显示器+鼠标也是同样支持的。

当然,LVGL可以实现的远不止于此,快快开发你的脑洞,完成更多的大作吧!!!

本文内容整理自 博学谷狂野架构师

多线程概述

file

基础概念

进程和线程

进程是程序运行资源分配的最小单位

​ 进程是操作系统进行资源分配的最小单位,其中资源包括:CPU、内存空间、磁盘IO等,同一进程中的多条线程共享该进程中的全部系统资源,而进程和进程之间是相互独立的。进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

​ 进程是程序在计算机上的一次执行活动。当你运行一个程序,你就启动了一个进程。显然,程序是死的、静态的,进程是活的、动态的。进程可以分为系统进程和用户进程。凡是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身,用户进程就是所有由你启动的进程。

线程是CPU调度的最小单位,必须依赖于进程而存在

​ 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的、能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

线程无处不在

​ 任何一个程序都必须要创建线程,特别是Java不管任何程序都必须启动一个main函数的主线程; Java Web开发里面的定时任务、定时器、JSP和 Servlet、异步消息处理机制,远程访问接口RM等,任何一个监听事件, onclick的触发事件等都离不开线程和并发的知识。

CPU核心数和线程数的关系

多核心:也指单芯片多处理器( Chip Multiprocessors,简称CMP),CMP是由美国斯坦福大学提出的,其思想是将大规模并行处理器中的SMP(对称多处理器)集成到同一芯片内,各个处理器并行执行不同的进程。这种依靠多个CPU同时并行地运行程序是实现超高速计算的一个重要方向,称为并行处理

多线程: Simultaneous Multithreading.简称SMT.让同一个处理器上的多个线程同步执行并共享处理器的执行资源。

核心数、线程数:目前主流CPU都是多核的。增加核心数目就是为了增加线程数,因为操作系统是通过线程来执行任务的,一般情况下它们是1:1对应关系,也就是说四核CPU一般拥有四个线程。但 Intel引入超线程技术后,使核心数与线程数形成1:2的关系

file

CPU时间片轮转机制

file

为什么感受不到CPU线程数的限制

我们平时在开发的时候,感觉并没有受cpu核心数的限制,想启动线程就启动线程,哪怕是在单核CPU上,为什么?这是因为操作系统提供了一种CPU时间片轮转机制。

​ 时间片轮转调度是一种最古老、最简单、最公平且使用最广的算法,又称RR调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。

什么是CPU轮转机制

百度百科对CPU时间片轮转机制原理解释如下:

​ 如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结来,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾

时间片长度

​ 时间片轮转调度中唯一有趣的一点是时间片的长度。从一个进程切换到另一个进程是需要定时间的,包括保存和装入寄存器值及内存映像,更新各种表格和队列等。假如进程切( processwitch),有时称为上下文切换( context switch),需要5ms,再假设时间片设为20ms,则在做完20ms有用的工作之后,CPU将花费5ms来进行进程切换。CPU时间的20%被浪费在了管理开销上了。

​ 为了提高CPU效率,我们可以将时间片设为5000ms。这时浪费的时间只有0.1%。但考虑到在一个分时系统中,如果有10个交互用户几乎同时按下回车键,将发生什么情况?假设所有其他进程都用足它们的时间片的话,最后一个不幸的进程不得不等待5s才获得运行机会。多数用户无法忍受一条简短命令要5才能做出响应,同样的问题在一台支持多道程序的个人计算机上也会发

​ 结论可以归结如下:时间片设得太短会导致过多的进程切换,降低了CPU效率:而设得太长又可能引起对短的交互请求的响应变差。将时间片设为100ms通常是一个比较合理的折衷。

​ 在CPU死机的情况下,其实大家不难发现当运行一个程序的时候把CPU给弄到了100%再不重启电脑的情况下,其实我们还是有机会把它KILL掉的,我想也正是因为这种机制的缘故。

澄清并行和并发

​ 我们举个例子,如果有条高速公路A上面并排有8条车道,那么最大的并行车辆就是8辆此条高速公路A同时并排行走的车辆小于等于8辆的时候,车辆就可以并行运行。CPU也是这个原理,一个CPU相当于一个高速公路A,核心数或者线程数就相当于并排可以通行的车道;而多个CPU就相当于并排有多条高速公路,而每个高速公路并排有多个车道。

当谈论并发的时候一定要加个单位时间,也就是说单位时间内并发量是多少?离开了单位时间其实是没有意义的。

​ 俗话说,一心不能二用,这对计算机也一样,原则上一个CPU只能分配给一个进程,以便运行这个进程。我们通常使用的计算机中只有一个CPU,也就是说只有一颗心,要让它一心多用同时运行多个进程,就必须使用并发技术。实现并发技术相当复杂,最容易理解的是“时间片轮转进程调度算法”。

综合来说:

并发:指应用能够交替执行不同的任务,比如单CPU核心下执行多线程并非是同时执行多个任务,如果你开两个线程执行,就是在你几乎不可能察觉到的速度不断去切换这两个任务,已达到”同时执行效果”,其实并不是的,只是计算机的速度太快,我们无法察觉到而已.

并行:指应用能够同时执行不同的任务,例:吃饭的时候可以边吃饭边打电话,这两件事情可以同时执行

两者区别:一个是交替执行,一个是同时执行.

file 感觉上是同时发生的,但是微观上还是有区别的,并行是同意时刻发生的,并发是同一时刻交替执行

file

高并发的意义

由于多核多线程的CPU的诞生,多线程、高并发的编程越来越受重视和关注。多线程可以给程序带来如下好处。

1. 充分利用CPU的资源

​ 从上面的CPU的介绍,可以看的出来,现在市面上没有CPU的内核不使用多线程并发机制的,特别是服务器还不止一个CPU,如果还是使用单线程的技术做思路,明显就out了。因为程序的基本调度单是线程,并且一个线程也只能在一个CPU的一个核的一个线程跑,如果你是个i3的CPU的话,最差也是双核心4线程的运算能力:如果是一个线程的程序的话,那是要浪费3/4的CPU性能:如果设计一个多线程的程序的话,那它就可以同时在多个CPU的多个核的多个线程上跑,可以充分地利用CPU,减少CPU的空闲时间,发挥它的运算能力,提高并发量。

​ 就像我们平时坐地铁一样,很多人坐长线地铁的时候都在认真看书,而不是为了坐地铁而坐地铁,到家了再去看书,这样你的时间就相当于有了两倍。这就是为什么有些人时间很充裕,而有些人老是说没时间的一个原因,工作也是这样,有的时候可以并发地去做几件事情,充分利用我们的时间,CPU也是一样,也要充分利用。

2. 加快响应用户的时间

​ 比如我们经常用的迅雷下载,都喜欢多开几个线程去下载,谁都不愿意用一个线程去下载,为什么呢?答案很简单,就是多个线程下载快啊。

​ 我们在做程序开发的时候更应该如此,特别是我们做互联网项目,网页的响应时间若提升1s,如果流量大的话,就能增加不少转换量。做过高性能web前端调优的都知道,要将静态资源地址用两三个子域名去加载,为什么?因为每多一个子域名,浏览器在加载你的页面的时候就会多开几个线程去加载你的页面资源,提升网站的响应速度。多线程,高并发真的是无处不在。

3. 可以使你的代码模块化,异步化,简单化

​ 例如我们实现电商系统,下订单和给用户发送短信、邮件就可以进行拆分,将给用户发送短信、邮件这两个步骤独立为单独的模块,并交给其他线程去执行。这样既增加了异步的操作,提升了系统性能,又使程序模块化,清晰化和简单化。

多线程应用开发的好处还有很多,大家在日后的代码编写过程中可以慢慢体会它的魅力。

多线程程序需要注意事项

1. 线程之间的安全性

​ 从前面的章节中我们都知道,在同一个进程里面的多线程是资源共享的,也就是都可以访问同一个内存地址当中的一个变量。例如:若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

2. 线程之间的死锁

​ 为了解决线程之间的安全性引入了Java的锁机制,而一不小心就会产生Java线程死锁的多线程问题,因为不同的线程都在等待那些根本不可能被释放的锁,从而导致所有的工作都无法完成。假设有两个线程,分别代表两个饥饿的人,他们必须共享刀叉并轮流吃饭。他们都需要获得两个锁:共享刀和共享叉的锁。

假如线程A获得了刀,而线程B获得了叉。线程A就会进入阻塞状态来等待获得叉,而线程B则阻塞来等待线程A所拥有的刀。这只是人为设计的例子,但尽管在运行时很难探测到,这类情况却时常发生

3. 线程太多了会将服务器资源耗尽形成死机当机

​ 线程数太多有可能造成系统创建大量线程而导致消耗完系统内存以及CPU的“过渡切换”,造成系统的死机,那么我们该如何解决这类问题呢?

​ 某些系统资源是有限的,如文件描述符。多线程程序可能耗尽资源,因为每个线程都可能希望有一个这样的资源。如果线程数相当大,或者某个资源的侯选线程数远远超过了可用的资源数则最好使用资源池。一个最好的示例是数据库连接池。只要线程需要使用一个数据库连接,它就从池中取出一个,使用以后再将它返回池中。资源池也称为资源库。

多线程应用开发的注意事项很多,希望大家在日后的工作中可以慢慢体会它的危险所在。

本文由教研团队发布。

如果本文对您有帮助,欢迎和;如果您有任何建议也可或,您的支持是我坚持创作的动力。

转载请注明出处!

点亮 ⭐️ Star · 照亮开源之路

GitHub:https://github.com/apache/dolphinscheduler

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

精彩回顾

近期,BIGO 的大数据研发工程师许名勇在社区线上 Meetup 上给大家分享了主题为《DS 及 SPARK 在 BIGO 的应用和改进》的演讲。

主要介绍了 BIGO 如何使用 DophinScheduler 来调度以 SPARK 为主的多种类型的离线任务,以及为了满足业务需求、提升用户使用体验,在 DS 和 Spark 上所做的各种改进。

讲师介绍

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

许名勇

Bigo 大数据研发工程师

文章整理:白鲸开源-曾辉

今天的演讲会围绕下面三点展开:

  1. Apache DolphinScheduler 应用概况

  2. Apache DolphinScheduler 改进

  3. Apache Spark 改进

DS 应用概况

01 为什么选择DS?

我们原来的调度平台用过很多个,无一例外都碰到一些难以满足自身需求的痛点问题:

  • Oozie :查看日志不便,缺少任务状态统计、工作流数量多了后存在调度压力等;

  • Airflow : 需要用 python 代码来绘制 DAG,存在一定使用门槛;

  • Crontab:就更原始了,而且是单点,使用不便。

经过调研后,我们最后选择 DS 调度沿用至今,因为在一定层面上 DS 满足我们所有的需求。

对于我们团队内部来说,主要的优势是:

  1. 能对工作流 DAG 可视化进行编辑,简单易用,日志查看也比较方便。

  2. 去中心化的多 master 多 worker 架构,可以线性扩展,从而保证了高可用。

  3. 支持的任务类型很丰富,契合大数据生态,方便定制和改造。

  4. 还支持补数,这个功能很实用。

当然,选择 Apache DolphinScheduler 还有一个契机,我们正在自研一站式的数据开发平台,需要一个新的工作流调度系统,综合所有的因素最终促成了我们选择海豚调度。

02 DS 集群概况

DS 在我们生产环境运行有1年时间了,目前部署的情况是:1台 alert 服务,3台 api 服务,10 台 master 9台 worker,这些服务混合部署在10台物理机上。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

改造后的 DS 任务基本都是提交到 Yarn 上运行, Yarn 集群规模目前是有 2000 多台 node manager 节点,集群总共有 500 多 T内存、10多万 core。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

03 DS 作业概况

关于作业情况,目前已经完成了最主要的 Oozie 工作流迁移,现在日均调度 1.8W 多个工作流实例,5W 多个任务实例。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在夜里高峰时段同时有 2400 多个工作流实例运行,这些实例主要以 Spark、Sparksql、Shell、Python、Sqoop 节点为主。

2 DophinScheduler 改进

01 用户体验提升

为了提升用户体验,我们围绕降低开发成本,简化任务配置做了很多改进。

打通 OA ,免去注册。方便用户登录。对于这种公司内部系统来说,还需要注册显然是不太方便的。

然后在 DAG 编辑页面完成开发、上线、树形图查看、运行、定时管理等一站式操作,尽量让用户在一个页面就能完成工作流的各个操作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

树形图页面聚合了单个工作流定义的所有实例列表,这样可以更加清晰的看到属于当前工作流的实例。

首页提供定时调度概况。展示调度的实例成功与否的状态,这样用户对自己的定时调度最近运行的情况就可以一目了然,

增加页面分层级树形导航条,提供在项目、工作流、树形图页面快速切换等等。

因为用户是以项目为粒度组织工作流,一个用户可能会有多个项目,这个快速切换可以方便用户从一个项目下的工作流快速切到另一个项目下的工作流,提高用户的开发效率。关于工作流的体验改进我们还做了很多,因为篇幅有限,我就不展开来讲。如果您对此有兴趣,欢迎来社区跟我探讨。

在依赖选择方面,简化了依赖节点的配置。

原先配置一个依赖节点,是要先选择项目,再选择工作流,用户反馈使用起来不太方便,因此我们做了相关改进,在配置依赖节点的时候可以直接按工作流ID、工作流名称或工作流 owner 来搜索依赖工作流进行配置。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

搜索配图

我们还在首页的详情页面,提供了便捷查看上游依赖实例详情的入口,让用户一眼就能看到当前工作流实例的上游是哪个实例没有完成。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这样可以在出现任务延迟的时候方便排查是不是上游还没完成导致的。

除此之外,还新增了一张表来记录工作流的上下游关系,在保存和更新工作流定义的时候去更新这个依赖表,然后提供了工作流依赖关系查看功能,以树形图的形式展示一个工作流的所有上游或是下游。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们还支持了下游依赖的批量替换。比如,一个工作流可能有很多下游,这时因为业务需求可能希望用新的工作流替换原先这个工作流,就可以用这个功能同时把下游依赖也替换掉。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在补数方面,我们做了比较大的改进,其中最常见的业务场景,就是可以支持触发下游,用户在补数的时候可能会希望当前工作流补完了,带动下游工作流也一起补。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

那这种情况下补数去触发下游,其实也是一个工作流实例的 DAG 了,因此我们不仅支持查看补数的进度,还可以知道当前补数是补到哪个工作流的哪个调度时间。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

限制同一个调度时间的实例同时运行。这是因为如果一个下游有多个上游开始触发下游补数时,这个下游可能会补数补重,也就是同时有两个相同调度时间的补数实例在跑,当然用户如果误补数的话也有这种情况发生,所以我们做了限制来避免同时跑。

告警管理,我们把超时告警和失败告警整合到了定时调度配置页面来一起设置,并支持告警到值班组。因为我们实际需求是只需要对定时调度的实例去告警,其他手动运行或是补数的实例不需要告警,因此这两个超时和失败告警整合到定时调度配置页面,在配置调度的时候去配置告警。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

告警人可以填值班组,而不仅仅是用户,值班组里的成员每天都会排班。

超时和失败告警我们改成了用户如果没处理会每小时发一次告警,原先是发送一次就没了,这有可能会让用户遗漏,导致工作流没有得到及时处理。

如果用户不需要处理这个实例或者单纯想取消告警,我们也在实例上提供了取消告警的选择。用户也可以在工作流上屏蔽告警,并且可以同时屏蔽下游。在屏蔽时间范围内将不会发送告警。

最后还提供了工作流定时调度到期提醒功能。如果工作流即将到期,将会发送通知给用户,前端页面也会增加醒目的提示提醒用户工作流快过期了,要及时延期,避免影响工作流的正常调度。

02 系统层面改进

Worker 支持任务无需重跑的 failover。以前 Worker 重启,Worker 上正在运行的任务需要 Kill 重新提交。

这就有几个问题:

  1. 任务运行时间比较长,直接 kill 重跑代价大;

  2. 重跑比较浪费集群资源;

  3. 限制 worker 同时运行任务数量的上限;

我们对此的优化是改造任务提交方式,不管是 shell,还是 python,java 都提交到 yarn 上去执行,不在 Worker 本地执行。

对于 spark 和 spark-sql 任务,以 cluster 模式提交到 yarn 上,client 提交完成后进程立马结束,不在 Worker 上驻留。

同时在任务实例里记录提交到 yarn 上后的 app id 信息,提交成功后开启异步任务 track 在 yarn 上的执行状态。

如果 Worker 宕机,容错后可以由其他 Worker 接管这个任务,继续 track 在 yarn 上的运行状态。这样就实现了无需任务重跑的 failover。

Worker 任务只提交一次。我们目前使用的还是 1.3.8 版本,容错的时候有个比较大的问题,就是会把master/worker 启动后的实例也容错,这会导致任务重复提交,由于我们是把任务提交到 yarn 上执行,重复提交表现就是:同一个任务实例同一时间会在 yarn 上有多个作业在执行。

这会导致工作流跑的数据不对,另一个就是会严重堵塞集群,影响其他工作流的正常运行。

针对这个问题,我们做了相对应的措施。

  1. 在实例表增加一个字段,master/worker 容错时根据字段来来判断实例是否需要容错。

  2. 是在 master 端重试分发 task 时,优先分发到上一次分发的 worker。

  3. 提交到 yarn 的 task 设置 yarn tags,failover 后的 task 重新分发到 worker 后如果没有 app id 信息,则通过 yarn tags 检查 yarn 上该 task 是否已经提交或者在运行了。

通过这些措施来保证 worker 提交任务只提交一次。

降低对数据库的压力。目前使用的这个版本 master 对线程的使用过重,对数据库有比较大的压力。每个工作流实例和任务实例都独占一个线程,状态轮询存在很多数据库 IO 操作。

另外一个是依赖节点,比如存在24小时依赖类型,这种依赖类型每个小时实例需要查一次状态,一个依赖项就要查 24 次数据库,如果这种依赖节点比较多,又是集中在某几个时刻运行,那就有可能并发查询的量过大,导致数据库活跃连接数过高,甚至打满数据库连接池,造成严重的后果。

我们对此做的优化是

  1. 增大工作流实例和任务实例状态轮询的间隔;

  2. 实例表增加索引,加快 sql 查询速度;

  3. 依赖节点查询上游实例状态时通过随机化分散查询,降低同时查询的并发数;

  4. 增加缓存,减少不必要的重复查询;

这些措施一定程度上增加了依赖节点的执行时间,但避免了数据库活跃连接数过高的问题,提升了系统的稳定性。

支持 Spark 任务灰度

针对 Spark 节点和 sql 节点我们是以 Spark-submit 或者 Spark-sql 方式提交的,如果要变更 Spark,那在对 Spark 任务灰度的时候存在几个问题:

  1. 单个任务灰度可以添加 spark.yarn.archive 参数来指定 Spark 版本,但如果要批量灰度就不方便了;

  2. 我们也可以在 Worker 级别灰度,这样无法指定具体的工作流,也不好控制灰度规模。

因此,我们开发了灰度管理的功能。可以在前端操作,批量添加一批工作流到灰度列表,添加到灰度列表的工作流在 master 分发任务到 worker 时,应用上灰度信息。

并且可以按照任务类型和工作流 owner 筛选工作流来灰度,当工作流从灰度列表移除就表示取消灰度。

这样,就可以比较方便的对任务进行灰度升级。

3 Spark 改进

01 小文件合并

关于小文件合并,众所周知,小文件与 hdfs 是不友好的,太多的小文件会给 hdfs 带来严重的性能瓶颈。

而Spark作业并行度高的话又容易产生小文件,因此小文件合并对于 Spark 来说是十分有必要的。

小文件合并的实现方案有很多,比如可以在最后增加一个 shuffle 来控制文件数量

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们的方案是:在文件 commit 过程中去实现的。首先看 Spark 任务的文件提交机制,在 driver 端会先 setupJob,然后在 executor 端执行 task 的时候 setupTask,创建 task 临时目录,在 commitTask 的时候将数据文件从 task 临时目录转移到 job 临时目录。

最后 driver 端执行 commitJob 方法,将各个 task 任务提交的数据文件,从 Job 临时目录转移到 Job 的最终目标目录。

小文件合并方案是:在 driver 端 setup job 时,在 Job 最终目标目录下创建临时的 merge 目录,然后按照正常的流程将数据写到这个临时目录,在 driver commit job 之后,所有的数据文件都已经转移到了这个临时目录中。

此时去计算这个临时目录下每个分区路径下的数据文件的平均大小,如果只有一个文件或大于指定的阈值,就不需要合并,可以直接移动到最终目标目录。

如果小于指定阈值,则按照分区路径下文件大小之和除以阈值来计算合并后的文件数量,然后将分区路径下的文件读成 HadoopRDD 或 FileScanRDD,再按照计算的合并后文件数量进行 coalesce 操作,然后启动一个 Spark Job 将 RDD 数据写到最终目标目录中。

这个小文件合并方案在我们线上也应用了很长时间,虽然需要启动一个额外的 job,但仍然带来了较大的收益。比如,它大大减少了文件数量,减轻 NameNode 的负载压力。也降低了 Spark 作业 driver OOM 出现的概率,提高了数据读取效率,加快了执行速度。

02 AQE优化

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

关于 AQE 的优化。AQE 是 Spark3 的重要功能,通过收集运行时的统计信息,来动态调整后续的执行计划。AQE 主要有三个优化场景:动态分区合并、动态调整 Join 策略以及动态优化倾斜 Join ,实现原理就不在这里赘述了。

AQE 的进一步优化。

第一点,分区合并可以让 reducer 处理的数据量适中,但如果物理计划中存在 expand 算子,会导致数据膨胀,即使 reducer 读取的数据量适中但经过数据膨胀之后,也会造成极大性能倒退,这种情况不适合进行分区合并或是需要调整分区合并的大小,针对这种情况,我们选择了针对这个 stage 不进行分区合并的操作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

第二点,目前倾斜 Join 优化是根据分区数据量的大小来判断是否存在倾斜的,扩展倾斜 Join,可以支持收集分区的行数信息,这样既可以根据分区数据量大小,也可以根据分区的行数来判断一个分区是否倾斜。

第三点,我们利用收集到的行数信息,在合并分区时还会根据数据量大小和行数的比值来决定是否进行分区的合并。

AQE 的优化我们也上线了很长时间,可以说对大部分作业都缩短了运行时间,提高了执行效率。经过统计,开启 AQE 优化后,我们集群整体作业的平均运行时间缩短了 10%。

今天的分享就到这里,如果大家对我文章内容有任何问题,可以在社区里面来找我交流,感谢大家聆听和关注。

参与贡献

随着国内开源的迅猛崛起,Apache DolphinScheduler 社区迎来蓬勃发展,为了做更好用、易用的调度,真诚欢迎热爱开源的伙伴加入到开源社区中来,为中国开源崛起献上一份自己的力量,让本土开源走向全球。

参与 DolphinScheduler 社区有非常多的参与贡献的方式,包括:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

贡献第一个PR(文档、代码) 我们也希望是简单的,第一个PR用于熟悉提交的流程和社区协作以及感受社区的友好度。

社区汇总了以下适合新手的问题列表:https://github.com/apache/dolphinscheduler/issues/5689

非新手问题列表:https://github.com/apache/dolphinscheduler/issues?q=is%3Aopen+is%3Aissue+label%3A%22volunteer+wanted%22

如何参与贡献链接:https://dolphinscheduler.apache.org/zh-cn/community/development/contribute.html

来吧,DolphinScheduler开源社区需要您的参与,为中国开源崛起添砖加瓦吧,哪怕只是小小的一块瓦,汇聚起来的力量也是巨大的。

参与开源可以近距离与各路高手切磋,迅速提升自己的技能,如果您想参与贡献,我们有个贡献者种子孵化群,可以添加社区小助手 Leonard-ds ,手把手教会您( 贡献者不分水平高低,有问必答,关键是有一颗愿意贡献的心 )。

添加小助手时请说明想参与贡献,来吧,开源社区非常期待您的参与。

福建纵腾网络有限公司(简称“纵腾集团”)成立于 2009 年, 以“全球跨境电商基础设施服务商”为企业定位,聚焦跨境仓储与物流, 为全球跨境电商商户、出口贸易企业、出海品牌商提供海外仓储、商业专线物流、定制化物流等一体化物流解决方案, 旗下拥有谷仓海外仓 、云途物流 、WORLDTECH 等知名品牌 。

作者纵腾集团数据技术架构师 张彬华

随着纵腾集团业务的快速发展,各产品线提出的数据需求越发严格,而早期基于多套 CDH 大数据架构的技术栈和组件繁杂,开发和运维难度高、效率低,数据质量和时效难以保障,已无法满足当下数据分析需求,严重影响相关工作的开展。因此,纵腾集团在 2022 年正式引入 Apache Doris,基于 Apache Doris 构建了新的流批一体数据架构,同时建立了以 Apache Doris 为核心的数据中台。 构建过程中对读写时效性、服务的稳定性及高并发读写等多方面进行了优化,在这一过程中我们也积累了诸多实践经验,在此总结分享给大家。

早期架构

早期数仓架构主要分为两套基于 CDH 的大数据集群,这两套架构用于不同产品线的数仓需求、数据大屏和 BI 报表等应用。

图片

图片

这两套架构为独立的数据管道,具有耦合度低,集群间相互独立等特点,便于精细化管理。但随着业务需求的不断变化,这样的特点也引发出许多新的问题。

遇到的问题

  • 数据和数据质量缺乏管控,数据质量无法得到保证
  • 不同业务数据独立存储维护导致数据孤岛,不利于数据整合
  • 每个集群的机房分布不一,维护成本非常高
  • 集群间的技术栈和组件较多且存在差异性,对统一开发运维和数据整合都极具挑战性

架构选型

为了解决早期架构的痛点、更好满足日益严苛的数据需求,我们希望能有一款产品帮助我们快速构建流批一体的数仓架构、构建数据中台服务。

图片

我们对传统数仓、 实时数仓和数据湖进行了对比。从上图可知,传统数仓可以支撑超 PB 级的海量数据,但是交互查询性能相对差一些,偏离线场景,不满足我们对数据实时性的要求;数据湖可以支撑超海量的数据,支持数据更新,查询性能适中,但是数据湖近两年才开始应用,成熟度较低,使用风险较大;实时数仓适用 PB 级数据存储,支持数据更新且查询性能非常好。结合我们的要求,实时数仓与我们的使用和需求场景都比较贴合,因此我们最终决定选择实时数仓作为数据底座。

接着我们对市面上较为流行的三款实时数仓:ClickHouse、Apache Druid、Apache Doris 进行了选型对比,对比图如下:

图片

对比可知,Apache Doris 优势明显、性价比更高,具有独立主从架构简单、运维更灵活便捷、丰富的数据模型、优秀的查询性能和周全的生态规划等诸多优势,对比这三个产品,Apache Doris 最符合我们的选型要求。

新数据架构

图片

新数据架构基于 Apache Doris 简化了数据采集、存储和计算的流程:

  • 结合 DataHub 实现自研数据采集和周期管理
  • 通过 Seatunnel 集成 Flink Doris Connector 稍加改造实现全量加增量数据的一体化采集
  • 简化存储媒介,对 ClickHouse、Kudu、HBase 等技术栈进行收敛,由 Apache Doris 进行流批数据的统一存储
  • Apache Doris 为核心数据底座,结合 Apache Kyuubi 的 JDBC 引擎直连查询(自研)和 Spark 引擎中的 Spark Doris Connector 进行 ETL 开发(原生),统一计算引擎管理、权限管控和对外服务。

基于上述几点进行了数据应用开发及对外提供数据服务,构建了数据中台。

数据中台

我们以 Apache Doris 为核心底座创建了数据平台,核心功能包括:指标中心、数据中心、基础配置中心、即席分析和数据接口服务中心,其中指标中心和即席分析的数据主要来源于 Aapche Doris ,当前已上线几百个指标。

图片

数仓建模

我们结合 Apache Doris 的特性重新对数仓进行了建模,数仓分层与传统数仓类似,其中 ODS 数据为存量加增量一体的导入模式,同时为防止出现[随机查询结果问题],ODS 层最终选用 Unique 数据模型,相比于 Aggregate 模型可以实现写时合并(Merge-on-Write),有效提高数据实时性,且 Aggregate 模型查询性能更接近于 Duplicate 模型,对于 ODS 层是非常好的选择。

DIM/DED/DWS/ADS 层主要选用 Aggregate 数据模型;Aggregate 数据模型提供的四种聚合方式可以在大部分场景下达到事半功倍的效果,帮助我们快速应对不同的需求场景。

  • SUM: 能够高效实现 PV 类指标计算,但对于 UV 类的指标需要考虑预去重。
  • MAX/MIN: 常用于最大最小运单时间节点类指标或包裹体积/重量最大最小值的指标计算。
  • REPLACE_IF_NOT_NULL: 可以自动地过滤空值,非常便捷地实现仅记录最后一条数据,适用于大部分 DW 场景。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

数据导入

ODS 层的数据导入目前主要以 Stream Load 为主,在 HDFS 上的历史存量数据也会通过 Broker Load 或Spark Load 导入。DW 层数据主要以 insert into 方式导入,同时为减轻 Doris 内存压力,我们将部分 ETL 任务放到 Kyuubi On Spark 引擎上去计算,目前在 DolphinScheduler 每天平稳调度 Doris DW 任务有上万个,其中大部分为 T+1 任务,小部分为小时级任务。

图片

实践经验

图片

对于以 Apache Doris 为核心的新数据架构,我们规划了6个阶段进行运行测试,直至可以上线运行。(重点关注压测阶段和运行阶段,有一些调试优化经验分享给大家)

1、准备阶段

引入 Apache Doris 时是 2022 年 2月,因此选择当时最新版本 Apache Doris 0.15 Release 版本进行应用,主要考虑维度如下:

  • 支持事务性插入语句功能
  • 支持 Unique Key 模型下的 Upsert
  • 支持 SQL 阻塞 List 功能,可以通过正则、哈希值匹配等方式防止某些 SQL 的执行
  • 官方不支持跨两位版本号进行升级,而 0.15 为当时最新的 Release 版本,选用该版本利于后期版本升级
  • 可通过资源标签的方式将一个Apache Doris 集群中的 BE 节点划分为多个资源组,实现多租户和资源隔离
  • 该版本提供了官方认可的 Flink-Doris-Connector/Spark-Doris-Connector/DataX Doriswriter 等插件,利于ETL流程建设

2、验证阶段

该阶段主要是为了二次验证官方文档中介绍的功能是否满足我们的实际运用场景,比如生态扩展中的 Connector、外表联邦查询、各种 Load 方式、多租户隔离及物化视图等。

3、压测阶段

图片

压测阶段首先进行数据生成,数据集选用的是 TPC-DS 数据,接着根据 Doris 的特性对 DDL 和 SQL 等规则进行对应调整,最后通过脚本将数据导入到 Apache Doris 存储中,再通过自动化脚本进行查询及导入压测,最终将压测结果输出到 MySQL 表中,量化为图表进行展示。下方为本阶段的基本配置及压测过程介绍:

– 硬件环境

  • 内存:256G
  • CPU:96C
  • 硬盘:SSD 1.92T * 8

– 软件环境

  • Apache Doris 版本:0.15-release/1.0-release(该阶段进行时,1.0-release 版本刚好发布)
  • Apache Doris 集群:3 FE + 9 BE
  • 系统:CentOS Linux release 7.9.2009

– 数据集信息

我们生成了 1T、5T、10T 的 TPC-DS 数据集,1T 的数据集约有 30 亿数据量。

图片

查询压测

图片

压测过程中,最初使用 0.15-release 版本进行测试,正巧 1.0-release 版本发布,后决定更换为 1.0-release 版本进行后续的压测。下图是基于 1T 的 TPC-DS 数据在同等硬件配置环境下和某商业 MPP 数据库的对比结果:

图片

如图所示,Apache Doris 的查询压测性能优异,有着明显的性能优势,作为开源产品能够达到这样的效果是非常优秀也是十分不易的

导入压测

  • 导入方式:通过 DataX Doriswriter 以 StreamLoad 方式进行写入压测
  • 数据来源:为避免因 Source 端原因影响写入时效,选择 100 张相同大表,即 100 个并发从内网 Hive 中导入(例如 tpcds-ds 的 store_sales_1t 表)
  • 数据模型:选用 Unique 模型(模拟ODS层),同时为充分考虑 Compaction 性能及小文件场景,每张表设置 70 个 Tablet

经调整优化后,最大写入时效为 269 MB/S&680K ops/s,平均写入时效 70 MB/S&180K ops/s,写入时效大幅提升

图片

4、上线阶段

该阶段主要是确认 Apache Doris 上线需要的检查清单、预调参数、BE 资源组规划及用户权限的划分。

  • 检查清单:包括但不限于 FE & BE 端口、网络检查及 Apache Doris 的一些功能性验证,例如读写是否正常等。
  • 预调参数:确认优化后的 FE&BE 参数是否配置,是否开启、动态分区以及数据盘保存位置是否有误等。
  • BE 资源组:由于我们需要通过 Apache Doris 的多租户特性对不同的用户进行资源隔离,所以需要提前规划好每个 BE 节点对应的资源组。
  • 用户权限:对于不同的用户群体提前规划好权限范围,比如分析师开发只需要权限,而 ETL 工程师需要、LOAD_PRIV和权限。

5、宣导阶段

该阶段主要是输出前面各阶段的 TimeLine、总结以及上线后使用 Apache Doris 的注意事项说明,比如我们用到多租户隔离,那么 DDL 建表时则需要在 Properties 中显示指定各副本对应的资源组:


6、运行阶段

Tablet 规范问题

问题描述: 上线运行一段时间后,随着越来越多的数据增长,集群每次重启后一周左右,读写就会开始变得越来越慢,直到无法正常进行读写。

问题处理:

  • 经过对生产和 UAT 环境的对比测试以及对数仓表的 Schema 的分析,我们发现有些表数据并不大,但是 Bucket 却设置的非常大。

图片

  • 结合命令,我们将整个集群所有表的 Bucket 信息罗列出来,明确了大部分表的 Bucket 设置的不合理;而当前集群共 20T 左右数据,平均 1T 数据近 10W 个 Tablet,这就会导致小文件过多,造成 FE 数据负载过高,从而影响导入和查询性能。
  • 定位原因后与社区小伙伴二次确认,并根据官方建议将 Bucket 设置不合理的表全部调整,调整后集群逐步恢复读写正常。(即将发布的 Apache Dorie 1.2.2 版本将推出 Auto Bucket 动态分桶推算功能,可以根据历史数据和机器数目自动推算新建 Partition 的分桶个数,保证分桶数始终保持在合理范围内,可有效解决上述问题)

问题小结:

  • Tablet数 = 分区数 * 桶数 * 副本数
  • 1TB 数据的 Tablet 数量控制在 8000 个左右(三副本控制到 2.4W 左右)
  • 建议大表的单个 Tablet 存储数据大小在 1G-10G 区间,可防止过多的小文件产生
  • 建议百兆左右的维表 Tablet 数量控制在 3-5 个,保证一定的并发数也不会产生过多的小文件

集群读写优化

问题描述: 1.1.3 release 版本中,高并发的同时进行 Stream Load、Broker Load、insert into 和查询时,读写会变得非常慢,如下图 11/01 19:00 并发上来后的 Txn Load 所示:

图片

问题处理:

1. 我们进行了十几轮对比测验,结论如下:

    • 写入速度与并发的增长成反比(但不会骤变,而是缓慢变化)
    • 单表 Bucket(Tablet)设置过大会导致集群写入速度骤减;例如 A 库的 TA 表,设置 80 个 Bucket 时,启动相关 Flink Sink Job 就会导致集群整体写入速度迅速变慢,降低 Bucket(9~10个)时写入恢复正常。
    • 的 ETL 任务与 Stream Load 写入任务会进行资源抢占,同时并发运行会使整个集群读写变慢。

图片

2. 通过发现,80 个 Bucket 表写入某个 Tablet 的数值比 10 个 Bucket 写入时的数值呈数倍之差,即 80 个 Bucket 表的数据写入时效无论 Memsize 还是 Flushsize 都非常小、但花费时间却很长。

图片

3. 同时收集 Pstack 日志,经过分析可以确定,Tcmalloc 在频繁地寻找,导致高频竞争锁从而降低了读写性能。

图片

4. 于是,进行如下参数调整:


5. 调参并滚动重启 BE 后,集群状况如下图所示:

18:50 前将 Broker Load、insert into 和查询任务同时开启,18:50 后将 Stream Load 任务也开启(包括 80 bucket的表),集群整体的读写性能不仅没有下降,反而 Stream Load 时效突破了压测阶段的最大值 269 MB/S&680K /ops/s,并且持续稳定。

图片

问题小结:

使用 Apache 1.1.3 及以上版本,非常推荐调整 Tcmalloc 相关参数,减少进程与系统之间的内存申请回收过程,可明显减少锁竞争的现象,大大提升读写性能和集群稳定性。(从 Apache Doris 1.1.5 版本开始,增加了Tcmalloc 简化配置,可将众多 Tcmalloc 参数归约到参数中,compact 为节约内存模式,performance 为性能模式,用户可根据实际需求进行调整)

总结收益

当前 Apache Doris 的生产集群为 3 FE + 9 BE 组合, 已导入集团存量和增量数据的 60%以及部分 DW 数据生成,3 副本共占 44.4TB 的存储。

图片

依赖 Apache Doris 自身优异特性及其生态圈帮助我们快速构建了一套新的流批一体数据架构,平均每天实时入库的数据量达到上亿规模,同时支持上万个* 调度任务平稳运行,相比早期架构单表查询效率提升近 5 倍 ,数据导入效率提升近 2 倍*,内存资源使用率显著减少。除此之外,Apache Doris 以下优势也是我们快速构建数据架构的重要推动力:

  • 扩展表:联邦查询的设计,便于集成其它存储
  • 数据表设计:丰富的数据模型,可快速应对不同的数据需求。
  • 数据查询:不同的 Join 算子结合自身完善的优化器,让查询快而稳。
  • 架构设计:架构清晰明了且运维简单,大大地降低了我们的运维成本。
  • 数据导入:各种 Load 方式及 Connector 的扩展,基本涵盖大部分的数据同步场景应用。
  • 活跃度:社区高度活跃,SelectDB 为 Apache Doris 社区组建了一支专职技术支持团队,疑难杂症基本能在 12H 内快速响应并有社区小伙伴跟进和协助解决。

未来规划

结合当下业务场景的考虑,未来我们将引入数据湖进行非结构化和结构化数据一体存储,进一步完善流批一体架构。同时也会将 Apache Doris 回归它最本质的定位,专注于 OLAP 分析场景,并通过 Apache Doris 统一湖仓查询引擎层,发挥其最大的功效。

图片

最后,非常感谢 Apache Doris 社区和 SelectDB 团队的张家锋、曲率和杨勇强等小伙伴对我们无私的技术支持,未来我们也将持续参与 Apache Doris 社区建设中,贡献绵薄之力。祝 Apache Doris 社区和 SelectDB 越来越好,日臻完善!

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。

系统完全开源,基于 Apache 2.0 开源协议,免费且不限制商业使用。

系统演示

功能特性

  • 丰富的模块市场,后台一键快速安装
  • 会员模块通用且完整,支持完整的API调用
  • 大文件分片上传,进度条显示,已上传文件管理
  • 强大的模块扩展功能,所有模块可以无缝集成,支持在线安装、卸载模块
  • 完善的开发助手,实现模块、主题的的一键创建
  • 完善的后台权限管理,支持基于RBAC的权限管理系统
  • 后台管理支持使用手机、平板、PC,无论何时何地都可方便管理
  • 第三方登录(、微信、微博、支付宝、微信小程序)
  • 第三方支付支持(微信、支付宝、支付宝当面付、微信扫码、微信小程序)
  • 第三方云存储支持,支持云储存分片上传(阿里云、百度云、华为云、腾讯云、FTP、七牛云、UCloud、又拍云)
  • 第三方短信支持(阿里云、腾讯云、华为云、百度云、253云通讯、聚合、七牛云、融云、赛邮、UCloud、云片、网易云)

V5.7.0版本更新

2023年02月08日ModStartCMS发布v5.7.0版本,增加了以下12个特性:

  • [新功能] 系统Meta信息工具包
  • [新功能] Grid中新增和修改弹窗默认增加窗口关闭方法
  • [新功能] MS.header前端组件对象获取支持多个头部
  • [新功能] 后台登录背景默认为纯色背景
  • [新功能] 系统打包支持系统Meta信息
  • [系统优化] 新窗口新增页面兼容多标签模式
  • [系统优化] 导入页面兼容后台多标签方式展示
  • [系统优化] 后台管理员日志记录数据序列化优化
  • [系统优化] 多层代理获取真实IP异常问题
  • [Bug修复] 导航轮播适配最新版本方法调用
  • [Bug修复] 后台多标签页面关闭窗口样式激活修复
  • [Bug修复] 组件SelectRemote和CanCascade条件显示异常问题

模块市场一键安装

系统内置模块市场,有行业应用、插件、云存储、云短信等功能模块,后台支持一键安装、启用、禁用、卸载,可快速搭建属于自己的系统应用。

功能模块

系统演示与文档

  • 码云仓库:https://gitee.com/modstart/ModStartCMS
  • Github仓库:https://github.com/modstart/ModStartCMS
  • 系统演示:https://cms.demo.tecmz.com/
  • 下载试用:https://modstart.com/download
  • 开发者文档:https://modstart.com/doc
  • 模块市场:https://modstart.com/store

 

OAuthApp 是一个前端发布工具,用于快速开发前端网页项目,并发布到服务器。
具有引入脚本库就能使用服务端 API、在线发布 H5、站点数据独立存储的特性。

2023-2-8 主要更新

1,[新增]用户管理 增加按角色筛选。
2,[优化]站点日志采集优化。
3,[优化]数据库迁移到应用站点下。 
4,[新增]数据自动备份。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

相关链接:
网址:https://www.oauthapp.com/
文档:https://web.oauthapp.com/4/docs

相关截图

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

漏洞描述

Dompdf 是一个用 php 编写的 HTML 到 PDF 转换器。

2.0.3 之前版本的 Dompdf 和 php-svg-lib(用于解析 svg 文件)的属性解析器不同:在解析 image 标签的 href 属性时,如果同时指定了 和 属性值,Dompdf 解析器解析 xlink:href 属性值,而 php-svg-lib 优先解析 href 属性值。如果攻击者可向 Dompdf 提供 SVG 文件,则可通过提供空的 属性绕过 Dompdf 端的保护,进而以任意协议调用任意 URL,导致文件删除或远程代码执行。

漏洞名称 Dompdf <2.0.3 存在解释冲突漏洞 漏洞类型 解释冲突 发现时间 2023-02-08 漏洞影响广度 小 MPS编号 MPS-2023-3319 CVE编号 CVE-2023-24813 CNVD编号 –

影响范围

dompdf/dompdf@[0.6.0, 2.0.3)

修复方案

升级dompdf/dompdf到 2.0.3 或更高版本

参考链接

https://www.oscs1024.com/hd/MPS-2023-3319

https://nvd.nist.gov/vuln/detail/CVE-2023-24813

https://github.com/dompdf/dompdf/commit/95009ea98230f9b084b040c34e3869ef3dccc9aa

https://github.com/dompdf/dompdf/security/advisories/GHSA-56gj-mvh6-rp75

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2023年2月7日,国产汽车基础软件厂商国科础石正式对外发布础光操作系统整体规划及开源计划,并率先将应用在智能汽车座舱域、自动驾驶域的础光Linux进行开源,以此作为国科础石开源计划实施的起点。

开源地址:https://gitee.com/kernelsoft

国科础石计划在2023年逐步开源础光Linux、础光实时操作系统及础光虚拟机管理器(Hypervisor),2024年将面向自动驾驶域的础光智能操作系统进行开源;同时对于智能汽车更大算力、更高实时、更加中央化的计算架构、更复杂的安全和隐私的计算需求,启动全新车用操作系统内核的研发工作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

国科础石是一家面向汽车和自主无人系统领域的基础软件厂商,开展汽车基础软件技术研究,发展操作系统、中间件等基础软件产品。

此次发布的汽车操作系统整体规划是面向目前智能汽车在座舱域、自动驾驶域、车控域等领域的操作系统需求,建设础光Linux、础光实时操作系统及础光虚拟机管理器(Hypervisor)等产品。同时针对未来汽车多域融合和计算集中的发展趋势,打造面向下一代智能汽车的汽车操作系统整体解决方案及支持多核异构环境下的混合关键内核操作系统。

此次开源的础光Linux基于Linux 5.10版本进行改造,从中断线程化、调度策略、进程切换等方面进行了优化,支持抢占式内核,并且针对性能、安全性、可靠性等方向进行了内核优化和性能效率提升,构建专注于仪表、娱乐、自动驾驶场景下安全、可靠的强实时汽车操作系统。通过开源实时性测试工具cyclictest测试,典型硬件平台上础光Linux在大压力环境下的中断延迟和调度延迟的最高延迟时间可以控制在100us以内。

目前Linux操作系统已经在汽车领域逐渐进入应用阶段,但Linux操作系统在设计之初是专门为服务器运行而设计,在实时性、安全性、可靠性等方面尚未做到较好地支持车规级应用。此次国科础石推出础光Linux开源版本,同时也将企业在操作系统内核上做的优化实践和经验分享给行业,推进行业共建。此外,针对汽车行业对功能安全的特殊要求,础光Linux还将持续进行功能安全特性开发。优化操作系统内核的中断、内存、调度处理流程,将影响功能安全的操作系统内核异常事件以可靠的方式通知业务软件,帮助实现系统整体功能安全。国科础石后续将与更多企业合作,持续对该项目进行性能优化和维护,共同打造一个标准的、符合汽车应用需求的Linux版本。

随着汽车产业的发展,硬件逐渐趋于标准化,软件已成为汽车产业发展和企业竞争的核心焦点。其中操作系统是软件发展的基础,底层操作系统的安全性、稳定性、可靠性是整车安全和性能的保障。

目前业内缺乏车规级的开源操作系统,缺乏对未来汽车整车操作系统的体系性规划和开源计划,缺乏良好的开源协作生态。国科础石秉承“技术创新驱动+生态开源开放“的理念,希望能解决汽车基础软件核心技术问题。截止目前,面向汽车产业所需的符合车规标准的汽车操作系统,国科础石在标准、性能、可靠性、安全性、测试等方向开展持续深入研究,已经构建了一支技术力量过硬的操作系统团队,能够为行业提供专业的汽车操作系统定制及技术支持等服务,促进汽车开源操作系统走向实际应用。

国科础石总裁薛云志表示,国科础石将加大力度拥抱开源,积极参与国内外开源组织。目前已加入OpenSDV汽车软件开源联盟,计划接下来将操作系统项目陆续开源并贡献给该联盟,同时将持续对开源项目进行代码贡献,积极参与支持社区建设。在此,也欢迎国内外广大车企、相关产学研机构及开发者共同参与开源共建,促进汽车基础软件的良性发展。

消息来自:国科础石公众号

2月8日,龙芯中科发布公告称,公司撤诉对上海芯联芯提起的关于3A5000处理器不侵犯MIPS指令系统的计算机软件著作权的诉讼案(案件1);同时,上海芯联芯针对公司LoongArch和3A5000处理器的诉讼案(案件2)已判决,北京知识产权法院判决驳回原告上海芯联芯的全部诉讼请求。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

据披露,龙芯中科于2021年4月23日向北京知识产权法院对上海芯联芯智能科技有限公司提起《民事起诉状》,请求判令确认公司3A5000处理器不侵犯MIPS指令系统的计算机软件著作权。

同时,龙芯中科于2021年11月19日收到广州知识产权法院送达关于上海芯联芯对公司提起针对LoongArch和3A5000处理器的诉讼(案件2)。广州知识产权法院已于2022年1月26日出具(2021)粤73知民初1456号《民事裁定书》,由于本案“与北京知识产权法院审理的另案是基于同一法律事实而发生的纠纷。如果本案由本院继续审理,则无异于浪费司法资源,增加当事人的诉累。由于北京知识产权法院审理的另案立案在先,故本案应当移送北京知识产权法院合并审理”,裁定:龙芯中科对管辖权提出的异议成立,本案移送北京知识产权法院处理。

关于案件1撤诉原因,龙芯中科表示,由于诉讼案件1与移送北京知识产权法院的诉讼案件2已合并审理,且两起案件系基于同一法律事实而发生的纠纷,因此公司向北京知识产权法院提出对诉讼案件1的撤诉申请,法院已准许撤诉。

而案件2,法院除了驳回上海芯联芯的全部诉讼请求外,341,800案件受理费也由上海芯联芯负担。

龙芯中科表示,上述诉讼结果情况均不会对公司的日常生产经营及损益产生负面影响。公司董事会将密切关注和高度重视公司诉讼事项,积极应诉,依法主张自身合法权益,采取相关法律措施,切实维护公司和股东的利益。

就在龙芯中科发布上述公告后,上海芯联芯在其官网发布声明称,公告中所涉龙芯中科LoongArch以及相关处理器被起诉的知识产权侵权诉讼,其结果目前尚不具有法律效力,在合适时间我司会继续采取合适行动,以维护我司的合法权益。同时,龙芯中科的相关其他法律行动仍在进行中。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


据了解,二者的争议起源于龙芯最初选择的 MIPS 路线。龙芯刚起步时使用的 LoongISA 架构是以 MIPS 为基础扩展而来。龙芯在 3A4000 以前的 LoongISA 是基于 MIPS 进行添加,3A5000 则基于龙芯自主指令集 LoongArch。

上海芯联芯公司成立于 2018 年,2021 年上海芯联芯一次性付清所有 MIPS 技术授权费获得了在中国对 MIPS 技术独占权利人和独家经营权人的地位

然而上海芯联芯公司却对龙芯中科后来自研的 LoongArch 架构以及 3A5000 处理器提起诉讼,认为龙芯指令集侵害 MIPS 指令集著作权。对此龙芯中科进行了反诉。

 <script src="https://res.zvo.cn/translate/translate.js"></script> <script> translate.setUseVersion2(); //设置使用v2.x 版本 translate.language.setLocal('chinese_simplified'); //设置本地语种(当前网页的语种)。如果不设置,默认就是 'chinese_simplified' 简体中文。 可填写如 'english'、'chinese_simplified' 等,具体参见文档下方关于此的说明。 translate.execute();//进行翻译  </script> 

IJPay 让支付触手可及,封装了微信支付、 支付、支付宝支付、银联支付、京东支付、PayPal 支付等常用的支付方式以及各种常用的接口。不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

特别说明:

  • 不依赖任何第三方 MVC 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。
  • 微信支付支持多商户多应用,普通商户模式与服务商商模式当然也支持境外商户、同时支持 Api-v3 与 Api-v2 版本的接口。
  • 支付宝支付支持多商户多应用,签名同时支持普通公钥方式与公钥证书方式

 

以后版本更新迭代会同时发布多个版本,标准版本使用JDK 1.8,其他版本会在标准版本号后面加JDK版本号,本次更新主要是支持 SpringBoot3, 并提供 SpringBoot3版本示例。
    

欢迎大家贡献代码,任何支付问题,欢迎在此一起探讨 右上角 – 我要提问

Node.js 版本微信支付: TNWX 微信系开发脚手

OrientDB 是兼具文档数据库的灵活性和图形数据库管理链接能力的可深层次扩展的文档 – 图形数据库管理系统。可选无模式、全模式或混合模式。支持许多高级特性,诸如 ACID 事务、快速索引、原生和 SQL 查询功能。可以导入 JSON 格式、导出文档。

OrientDB 发布了 3.2.16  版本,此版本更新如下:

  • 删除了在添加到事务之前缓冲更改的需要
  • 确保在关闭 OrientDB 实例之前停止视图的刷新计划
  • 改进了视图的刷新和清理
  • 在增量序列化中处理错误输入记录的小修复
  • 释放索引管理器锁时,对数据快照逻辑的小修正
  • 确保对遗留索引的实现也使用事务感知流  9914
  • 减少存储进入只读模式的次数,并允许删除非空数据结构
  • 确保模式快照在索引加载时可用  #9915
  • 更改索引管理器和视图实现以避免更新期间的交叉锁定
  • 在视图中交换集群时,避免重新索引新集群。
  • 确保在系统数据库之前初始化超时检查器

更新公告:https://github.com/orientechnologies/orientdb/releases/tag/3.2.16

Endless Foundation 已正式发布 Endless OS 5.0 ,此版本基于 Debian GNU/Linux 11 “Bullseye”,桌面建立在 GNOME 41 桌面环境之上,并运行在下一代Wayland 显示协议之上,以改进隐私、安全和 X11 的性能提升。

新的默认壁纸

https://support.endlessos.org/release-notes-5.0.0-desktop-with-apps.png

由于 Endless OS 是一个以应用程序为中心的操作系统,新版本附带了一个全新的应用程序中心。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Endless OS 5.0 还附带了更多采用 Flatpak 格式的应用程序,其中包括 File Roller、GNOME 计算器、GNOME 联系人、GNOME 字体、GNOME 日志、Shotwell 和 Gedit。

改进多 GPU 支持

在 EOS 5.0.0 之前,当一个系统有一个以上的显卡(即一个与 CPU 集成的显卡和另一个独立显卡),系统 UI 和所有应用程序总是在独立显卡上运行。虽然这提供了最好的性能,但这是以电池寿命为代价的。从 Endless OS 5.0.0 开始,系统 UI 和大多数应用程序在集成显卡上运行,带来了显著的能源节约,而那些已知有更多图形需求的应用程序,如 3D 游戏,会自动在独立显卡上启动。

用户还可以手动在独立显卡上启动任何应用程序,方法是长击应用程序启动器图标并选择 “使用独立显卡启动”。

https://support.endlessos.org/screenshots/screenshot_launch_using_discrete_graphics_card.png

其他值得注意的变化包括系统设置中的家长控制功能、OSTree 2022.1 等,更多内容可查看更新公告。

 

Electron 是一个使用 JavaScript、HTML 和 CSS 构建跨平台的桌面应用程序。它基于 Node.js 和 Chromium,被 Atom 编辑器和许多其他应用程序使用。Electron 兼容 Mac、Windows 和 Linux,可以构建出三个平台的应用程序。

Electron v23.0.0 现已发布,具体更新内容如下:

Fixes

  • 当激活 macOS 语音控制以允许对 Electron 应用程序进行完全语音控制时,现在会启用基本辅助功能支持。#37145
  • 修复了由未初始化的 pref 引起的 printing 崩溃。#37149

Other Changes

  • 已弃用的/方法已被删除。#37148
  • 将 Chromium 更新为 110.0.5481.77。#37120

更新说明:https://github.com/electron/electron/releases/tag/v23.0.0 

 

njs 0.7.10 已发布。njs 以 nginx 插件的方式存在,它是 JavaScript/ECMAscript 的子集,实现了大部分的 JavaScript 语言功能,没有完全遵从 ECMAScript 标准,同时抛弃了 JavaScript 比较难懂的部分。njs 不通过 V8 引擎实现,而是通过一个更小、能耗更低、更符合 nginx 应用场景的小虚拟机实现,可以理解成 nginx 为其实现了一套自己的词法解析。

作为 nginx 的插件,njs 的安装方式是重新编译 nginx。

新版本下载地址:http://nginx.org/en/docs/njs/install.html

主要变化

nginx modules:

  • Feature: 在 Fetch API 中添加,和ctors
  • Bugfix: 修复主进程中调用的 nginx 记录器回调

Core:

  • Feature: 为 CLI 添加对 signal 的支持
  • Feature: 添加用于处理 XML 文档的模块
  • Feature: 扩展了对WebCrypto API 中对称和非对称密钥的支持。最值得注意的是为添加了 格式,并且实现了和方法
  • Feature: 添加
  • Bugfix: 修复条件语法错误处理
  • Bugfix: 使用外部对象的 和 
  • Bugfix: 修复.

详情查看 Changelog。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Microsoft PowerToys 是 Windows 系统实用程序,供高级用户调整和简化其 Windows 体验,可最大限度地提高生产力。

这是一个补丁修复版本,以修复 v.67.0 中的一些问题,以下是 PowerToys v0.67.1 版本中的一些重要更新内容:

  • 修复 FancyZones 在使用 win+箭头在显示器之间移动窗口时崩溃的问题
  • 修复 FancyZones 导致窗口属性不能正确重置的问题
  • 将 PowerToys 注册表项移回 HKLM,以修复在某些配置上无法使用的上下文菜单项
  • 显示系统托盘布局时尊重任务栏的位置
  • 修复 Power Toys Run 在加载 PDF 文件的缩略图时崩溃的问题
  • 在 PowerToys 设置应用程序中显示正确的 Hosts 模块图像
  • 修复 FancyZones 的问题,导致改变布局时无法调整窗口
  • 修复拖动开始时导致问题不被取消的问题
  • 修复布局不被应用到新的虚拟桌面的问题
  • 修复缩略图崩溃的问题

更多详情可查看:https://github.com/microsoft/PowerToys/releases/tag/v0.67.1

Google 于今天发布了 Android 14 的首个开发者预览版,这一发布时间与以往的发布时间类似,预计 Android 14 正式版将于今年第三季度推出。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

支持多账户登录

一家人共用同一个设备的情况十分常见,尤其是共用平板电脑。除此之外,有些用户还可能会为了 “工作” 和 “生活” 两种使用场景分别创建两个账号。

在 Android 14 的首个开发者预览版中,Google 为 Android 添加了多用户模式,可以为不同场景或者不用用户创建账户。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

应用双开(Cloned Apps)

国内不少 Android 厂商都会在手机中内置应用双开功能,方便用户同时登录一个软件的多个帐户(例如不少人喜欢的微信双开)。

通过 Android 14 Developer Preview 1,Google 也正在准备一种官方方式来 “克隆” 应用程序,而无需借助任何第三方应用程序。现在只需前往新的 “Cloned Apps” 菜单,并选择想要克隆的 Android 应用程序即可。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

双 SIM 卡支持自动切换移动数据到最佳选项

Android 14 中,Google 增加了双卡双待自动切换到最佳移动数据选项的功能。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

屏幕时间

在 Android 14 的首个开发者预览版中,Google 重新设计了电池使用页面,突出显示 “自上次充满电以来的屏幕使用时间” 部分。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

任务栏

在 Android 14 首个开发者预览版中,当用户切换到平板电脑时,任务栏现在会在应用程序图标下方显示文本名称。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

字体

用户现在可以在 Android 14 中将字体大小最多缩放 200%,而 Android 13 最多可缩放 130%。Google 还将使用非线性字体缩放,这样已经很大的文本就不会再进一步增大了。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Android API

Google 调整了两个 Android API(前台服务和作业调度程序),以提高后台活动和下载大文件等任务的效率。

时间表

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

根据官方发布的时间表,Google 将会发布两个开发者预览版、四个测试版,最终版本有望在今年第三季度正式发布。

Android 14 的开发者预览版目前适配于以下设备:Pixel 4a(5G)、Pixel 5、Pixel 5A 5G、Pixel 6、Pixel 6 Pro、Pixel 7 和 Pixel 7 Pro。

更多详情可查看:https://android-developers.googleblog.com/2023/02/first-developer-preview-android14.html

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

作者暴渊,API7.ai 技术工程师,Apache APISIX Committer。

近些年随着云原生和微服务架构的日趋发展,API 网关以流量入口的角色在技术架构中扮演着越来越重要的作用。API 网关主要负责接收所有请求的流量并进行处理转发至上游服务,API 网关的策略决定了 API 网关处理这些流量的逻辑与规则,直接决定了实际的业务流量行为。

什么是 API 网关策略?

API 网关一般位于所有的上游服务之前,当用户向服务发送请求后请求会先到 API 网关,API 网关接收到请求之后一般会判断几件事情:

  1. 请求是否合法,比如是否来自被禁止访问的用户列表中;
  2. 这个请求是否通过认证,访问的内容是否是经过授权的;
  3. 请求是否触发了某些限制规则,比如限流限速等;
  4. 请求应该转发给哪个上游服务。

经过这一系列步骤,这个请求要么不符合预设的规则被拒绝,要么经过了层层处理正确到达指定的上游服务中。我们将这些处理规则称之为 API 网关的策略。这些规则由网关的管理员在网关运行时不断添加至网关中,网关接受这些规则并根据这些规则作出正确的流量处理行为。

以 API 网关 Apache APISIX 为例,APISIX 的配置信息有两种:网关启动用的配置文件,比如 ,这个文件决定了网关正常启动所必须的一些配置。另外在运行时管理员可以通过 Admin API 动态创建各种规则与配置,比如 Route、Consumer、Plugin 等等。API 网关的策略就是管理员通过 Admin API 动态创建的各种规则与配置。

本文不再额外描述基本常用场景,而是针对认证授权、安全、流量处理与可观测性这四类 API 网关中重要的场景进行阐述,介绍每种场景下包含的一些 API 网关策略的作用以及使用方法。

认证和授权策略

认证可以确认 API 调用者的身份,授权主要限制调用者仅能访问权限内的资源。

授权调用

比如说一位乘客前往车站出行,进入车站之前会使用身份证进行“认证”确认身份,在进入车站后出示车票,经工作人员确认后被“授权”进入某班列车。

认证授权类策略主要目的是保证网关转发到上游服务的所有请求都是经过认证和授权的,不会出现非法请求。并且访问的都是权限范围内的资源。比较常用的策略有下面几种:

Basic Auth

基本访问认证策略,这是一种最简单的访问控制技术。一般由用户的 HTTP 代理在发出请求时携带用于认证的请求头,一般为:,credentials 中即包含了用户认证需要的用户 ID 和密码,使用 隔离。这种方式不需要登陆页面、cookie 等繁杂的设置,仅仅基于请求头中的简单凭据信息进行认证,一般为用户名和密码,配置使用起来较为简单。

携带基本认证的 请求的示例如下,用户名为 ,密码为 :


需要注意的是 中的信息在传输过程中并不会被加密,仅仅做 Base64 编码,所以通常需要和 HTTPS 一起使用来保证密码的安全性。

在网关中实施这一策略后,未携带凭据的请求将无法正常通过网关转发,除非在请求中携带了正确的认证信息,实现了最小成本下为 API 添加了访问验证。

Key Auth

Key Auth 策略通过在 API 中添加 Key 来限制 API 调用,并识别请求携带的 Key 来进行访问资源的控制。只有携带了正确的 Key 之后的请求才能正常访问,可以在请求头中或 Query 中携带。通常还可以通过这个 Key 来区分不同的 API 调用方,从而可以针对不同的调用方实施不同的其他策略或资源控制。同样的 Key 在 HTTP 中是明文传输的,确保请求使用了 HTTPS 以保证安全。

以 APISIX 的 key-auth 插件为例,插件需要通过 Admin API 创建一个具有唯一 key 值的 Consumer:


这一请求创建了一个名字为 的 Consumer,它的 key 值为 。在路由中启用插件时需要配置网关从请求中读取 Key 值的位置和字段名称。默认的配置位置为 ,字段名称为 , 那么正确的请求这个路由的示例为:


APISIX 在收到这一请求后会从请求中解析出 Key,然后从配置的所有 Key 中找到和这个请求匹配的 Consumer ,这样网关就清楚这个请求是 发出的。如果没有找到匹配的 Key 即可判定为非法请求。

JSON Web Token

JSON Web Token (JWT) 是一个开放的标准,它定义了一种以 json 对象形式在各方之间安全传递信息的方式。JWT 策略可以集认证和授权于一身,在用户取得授权后会向用户传输一个 JWT Token,在后面的所有请求中调用方都会携带这个 Token 从而保证请求是被授权的。

在 API 网关中可以通过 JWT 策略将 JWT 身份验证能力添加到网关中,从而把这层逻辑从业务中抽离出来,业务实现者可以更加专注实现业务逻辑。以 APISIX 的 jwt-auth 插件为例,插件需要在 Consumer 中启用并配置唯一的 Key、加密用的公私钥、加密算法、Token 过期时间等。同时还需要在路由中启用这一插件并配置网关读取 Token 的位置和字段,比如 header、query、cookie 等。该插件会在 API 网关中添加一个 API 用于签发 Token。在发送请求之前需要请求签发 token 的 API 获得 Token,发送请求时需要根据配置信息在指定的位置上携带这一 Token。在请求到达网关后网关会按照配置信息从请求的指定位置读取 Token 并验证 Token 的有效性,验证通过后该请求才能被转发至上游服务。

相较于前两种策略,JWT 策略包含了过期时间选项,签发的 Token 随着时间流逝是可以过期的,但是 Basic Auth 和 Key Auth 的有效期是永久的,除非服务端更换了密码或 Key。除此之外 JWT 策略可以在多个服务之间公用,尤其是针对单点登录场景下很有用。

OpenID Connect

OpenID Connect 是建立在 OAuth2.0 协议之上的身份认证方法,为应用的授权提供了比较完整的方案,API 网关中的 OpenID Connect 策略将允许上游服务从身份提供者(IdP)中获取请求中的用户信息,从而保护 API 安全。常见的身份提供者有 Keycloak、Ory Hydra、Okta、Auth0 等等。以 Apache APISIX 为例网关中的 OpenID Connect 策略工作流程如下:

工作流程

  1. 客户端向网关发出请求
  2. 网关收到请求后向 IdP 发出认证请求
  3. 用户将被重定向到 IdP 提供的页面完成登陆认证
  4. IdP 重定向到网关并携带认证 code
  5. 网关通过 code 向 IdP 请求 Access Token 从而获取用户信息
  6. 网关向上游转发请求时即可携带用户信息

通过这一流程可以将认证和鉴权从业务中独立出来放置于网关中解决,使架构更加清晰。关于更多 APISIX 的认证授权方法可以参考 API Gateway Authentication。

安全策略

API 网关安全策略像门卫一样保证 API 安全访问,允许正常请求被网关转发并在网关上拦截非法请求。根据 OWASP API Security Project,在 API 的调用者中存在着大量可能的威胁和攻击。使用 API 网关安全策略可以对所有的 API 请求进行安全验证,在 API 免于遭受这些安全威胁上起到了重要作用。

安全策略

以下是几种比较重要的 API 网关安全策略。

IP 访问限制

IP 限制策略通过将某些 IP 或 CIDR 设置为白名单或者黑名单来限制某些客户端对 API 的访问,确保重要数据不会被随意访问。正确配置这一策略很大程度上提高了 API 的安全性,实现了更高的 API 安全治理。

URI 拦截

URI 拦截策略主要通过设置 URI 的一些规则来阻止潜在的危险 API 请求。比如一些安全攻击通过嗅探 URI 路径从而发现潜在的安全漏洞进而攻击。

Apache APISIX 提供了 插件来提供这一能力。通过 uri-blocker 插件可以设置一些正则规则,如果请求命中规则就可以拦截当前用户的请求,例如设置 、 ,这一插件就可以阻止 和 这种类似的请求,进一步保护 API 安全。

CORS

CORS 即浏览器针对跨域请求作出的安全策略。一般情况下在浏览器中发出 xhr 请求前浏览器会验证请求地址和当前地址是否为同一域,如果在同一域下请求可以直接发出,否则浏览器会先出发一个 OPTION 类型的跨域预检请求,然后在该请求的响应头中会有 CORS 相关的设置,例如允许跨域请求的方法、允许请求携带的凭据等。浏览器会根据这些信息决定是否发出正式的请求,详细可以参考 CORS。

一般情况下包含 CORS 设置的响应是由后端服务设置的,但是如果服务数量很多,在网关层面针对不同服务统一处理会更加便捷安全。CORS 策略可以在不同的 API 上设置不同的跨域解决策略,上游服务无需再处理这些逻辑。

CSRF

CSRF 即跨站请求伪造攻击,通常情况下会使终端用户在他们已经认证的站点中执行非自愿的动作。这种攻击通常伴随着社会工程学(通过电子邮件向攻击者发送攻击链接),当用户这一链接后利用攻击者在网站中已登陆认证的身份执行攻击操作。在网站看来因为用户已经登陆,所以所做的任何操作都是正常的。

通常网站的后端服务需要添加额外的中间件处理这部分逻辑,防范的方法也都有统一的标准。使用 CSRF 策略可以为网关提供防范这一攻击的能力,在网关层统一做 CSRF 安全处理,简化上游服务逻辑复杂度。

流量处理策略

流量处理策略主要保证 API 网关进行流量转发的上游负载都在健康范围内,同时在请求转发前或者返回给调用者前对请求进行按需改写。这一类型的策略主要围绕限流限速、熔断、缓存、重写等功能展开。

限流限速

在资源有限的情况下,API 可以提供的服务能力是有一定限度的,如果调用超过了这一限制可能会使上游服务崩溃继而引起一些连锁反应。限流限速可以防范这种情况的发生,另一方面也可以有效防止 API 遭受 DDOS 攻击。

在限流限速策略中可以设置一个时间窗口和可允许最大的请求数量,在时间窗口内超过这个数量的请求会被拒绝并返回设置的信息,直到请求数量低于设定的值或到下一个时间窗口后会允许继续访问。

请求计数的凭据可以设置为请求中的变量或着某一个请求头等,例如根据不同的 IP 设置相应的限速策略。实现更加灵活的控制。

熔断

API 熔断策略可以为上游服务提供熔断能力,使用这一策略时需要设置上游服务健康和不健康的状态码,用于网关判断上游服务状态。另外还需要设置触发熔断或者恢复健康的请求次数,连续达到这一次数后即判定为对应的状态。当上游服务连续向网关返回一定次数的不健康状态码后,网关就会熔断该上游服务一段时间,在这段时间内不再向该上游转发请求而是由网关直接返回错误。可以防止上游服务因为错误后继续接收请求出现 “雪崩”,保护业务服务。超过这一时间后网关会再次尝试向上游转发请求,如果还是返回不健康的状态码,网关就会继续熔断更长的时间(加倍)。直到转发请求后上游连续返回了一定次数的健康状态码,则网关认为上游服务恢复健康,后续会继续往该上游节点转发流量。

在这个策略中还需要设置当不健康后需要返回的状态码和信息,当上游服务不健康后请求在网关层面直接返回,保护业务服务稳定。

流量拆分

流量拆分策略可以动态控制将流量按比例转发给不同的上游服务,这在灰度发布或蓝绿发布中非常有用。

灰度发布又名金丝雀发布,当服务发布新功能时可以仅让一部分请求使用新的服务,另一部分仍然停留在旧的服务中。如果新服务保持稳定,则可以增加比例逐步将所有请求转移到新的服务中,直至比例完全切换,完成服务升级。

蓝绿发布则是另一种发布模式,可以做到在用户使用的高峰期进行发布,同时不会中断服务。服务的旧版本和新版本会同时共存。一般会将生产环境(蓝色)复制到一个相同但是单独的容器中(绿色)。在绿色环境中发布新的更新,之后将绿色和蓝色一同发布至生产环境。之后就可以在绿色环境中进行测试和修复,在这期间用户访问的还是蓝色系统。之后可以使用某些负载均衡策略将请求重定向到绿色环境中。蓝色环境即可保持待机作为灾难恢复选项或者用作下一次更新。

APISIX 的 traffic-split 插件通过流量拆分对上述提到的两种发布类型都进行了很好的支持,使得业务部署更加便捷可靠。

请求重写

在现代微服务架构中,尤其是服务端与服务、服务与服务之间充斥各种不同的协议,或着请求数据格式不统一,这些问题如果单独在各自服务之间实现转换处理会产生很多冗余的逻辑代码并且难以管理。一些请求重写策略可以处理一些协议转换、请求体改写等逻辑。

APISIX 提供了 response-rewrite 插件可以用来修改上游服务返回的 Body 或者 Header 信息内容,支持添加或者删除响应头,设置规则修改响应体等。这在设置 CORS 响应头实现跨域请求设置或者设置 Location 实现重定向等场景中很有用。

另一方面,对于请求重写 APISIX 则提供了 proxy-rewrite 插件也可以处理代理到上游服务的请求内容,可以对请求的 URI、方法、请求头等重写,在很多场景下为业务处理提供了便捷。

故障注入

故障注入测试是一种软件测试方法,通过在系统中故意引入错误来确保系统的行为正常。通常在部署之前进行测试以保证在生产环境中没有潜在的故障。在一些混沌测试场景下,需要对服务注入一些错误来验证服务的可靠性。

软件的故障注入可以分为编译时注入和运行时注入。编译时注入指在编写软件的过程中通过改变某些代码或逻辑来实现;运行时注入通过向正在运行的软件环境中设置错误来测试软件的行为。故障注入策略可以在网关中以运行时注入的方式,模拟应用网络请求中的故障。通过在策略中设置一个比例,命中这个比例内的请求会执行设置好的故障逻辑,比如延迟时间返回,或直接返回设置的错误码和错误信息给调用方。

通过这种方式可以增加软件的适应性,让开发人员提前看到可能出现的一些错误情况,在发布之前针对问题做出适应性修改。

协议转换

协议转换类的策略可以做一些常见协议之间的转换。比如常见的 HTTP 请求和 gRPC 之间的转换。Apache APISIX 提供了 grpc-transcode 插件可以实现在网关接收到 HTTP 请求之后,将请求转码并转发给 gRPC 类型的服务,接收到响应后以 HTTP 的格式返回给客户端。这样客户端无需关注上游 gRPC 的类型,只处理 HTTP 即可。

可观测性策略

可观测性指在一个系统中通过系统的输出数据来衡量这个系统运行状态的能力。在一些简单的系统中,因为系统组件数量相对较少,出现问题时可以通过分析各个组件状态得到答案。但是在大型分布式系统中,各种微服务组件数量非常大,对组件一一进行排查显然是不现实的,这个时候就需要系统具备可观测性。可观测性提供了对分布式系统的“可见性”,当系统出现问题时它可以提供工程师所需的控制能力,准确定位问题。

输出数据类型

可观测性的数据收集可以在应用程序组件内实现,也可以在其他位置实现。API 网关作为所有流量的入口,在 API 网关中实现系统的可观测性,可以清晰反映出系统 API 的使用情况。API 网关的可观测性策略可以帮助到公司的每个团队:

  • 工程师团队可以监控并解决 API 问题;
  • 产品团队可以了解 API 的使用情况以挖掘背后的商业价值;
  • 销售和增长团队可以监控 API 使用情况,观察商业机会并确保 API 提供正确的数据。

可观测性策略根据输出的数据类型一般分为三类:Tracing,Metrics 和 Logging。

Tracing

在大型分布式系统中服务之间的调用关系错综复杂,Tracing(链路追踪)可以在分布式应用中追踪完整的调用链路、应用之间的依赖分析以及请求统计等内容。在系统出现问题时可以帮助工程师确定排查范围和位置。

Tracing 策略可以在 API 网关上集成一些其他的分布式调用链路追踪系统,收集信息并记录。常见的服务比如 Zipkin、SkyWalking 等。通过 Tracing 策略将这些服务集成到 API 网关中,实现在网关上数据收集和与这些服务之间的通信,可以帮助工程师解决诸如这个请求接触了什么服务以及引入了多少延迟等问题。Tracing 策略使工程师能够进一步确认在特定的会话或相关的 API 调用中要看哪些日志,确认排查范围。

Metrics

Metrics 指在服务运行期间收集到的一个时间间隔内软件自己的各种观测数据,这些数据默认是结构化的,可以更好地实现查询和可视化。通过对这些数据分析可以掌握系统当下的运行状态和行为。

Metrics 策略可以在 API 网关中集成 Prometheus 或 Datadog 这一类服务,为系统提供监控、报警等能力。这一策略通过 API 网关中的各种接口收集网关运行过程中的数据,并将数据上报至上述服务中。通过将这些数据可视化后开发者可以清晰看到网关的运行状态,API 请求的统计信息等数据统计图。

Logging

日志是在某个特定时间系统事件的文本记录,当系统出现问题时日志是首要排查的地方。当服务出现一些意外情况时工程师依赖日志内容查看系统“发生了什么”从而找出对应的解决方法。日志内容一般分为两类:API 请求日志和网关自身的运行日志。API 请求日志记录了 API 网关在运行期间所有的 API 请求记录,通过这些记录工程师可以掌握 API 访问情况,及时发现并排查异常请求。网关自身的运行日志则包含了网关在工作期间发生的所有事件的记录,当 API 网关自身出现异常时可以作为排查问题的重要依据。

Logging 策略可以将 API 网关中的日志存储在服务器磁盘中或是推送到一些其他的日志服务器中,比如 HTTP 日志服务器、TCP 日志服务器、UDP 日志服务器等,或者是其他的日志系统比如 Apache Kafka、Apache RocketMQ、Clickhouse 等。

总结

这篇文章介绍了什么是 API 网关策略,并针对认证授权、安全、流量处理与可观测性这四类 API 网关中常用的策略进行描述。API 网关在所有上游服务之前接收请求的流量,控制一个请求是否要转发以及如何进行转发,对不安全的、未授权的请求直接拒绝或进行限制,这些行为都可以由 API 网关策略决定。

Masonry 是一个 Rust GUI 框架。

Masonry 提供了用于创建窗口的平台(使用 Glazier 作为后端),每个窗口都包含一个 Widget 树。它还提供了用于在 runtime 检测 Widget 树的工具,可编写单测试,方便开发者调试和维护应用程序。

基于 Masonry,开发者可实现即时模式 (immediate-mode) GUI、Elm 架构、函数式响应 GUI 等。

示例代码


V 社最新提交的 Steam HID 驱动补丁 添加对 Steam Deck 控制器的初始支持,一旦该补丁集在 Linux 6.3 中合并, 即意味着 SteamDeck 的手柄可以在 Linux 系统的任意应用中使用,而不仅限 Steam 客户端。

内核中的 Hid-Steam 板块最初是为支持 Steam 控制器手柄而创建的 HID 内核驱动程序。早在 2018 年,Rodrigo Rivas Costa 通过逆向分析为 V 社的 Steam Controller 手柄开发内核驱动程序,不过当时的驱动程序仅限用于 Steam Controller 手柄,且只有基础的按键/摇杆功能,在电池监控、震动反馈、加速度计/陀螺仪、LED 等方面表现不佳。

▼  Steam Controller 手柄

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

而 Linux 6.3 中针对  Steam Deck 手柄的最新驱动补集丁则由 V 社的员工 Vicki Pfau 进行提交,第一批补丁提供了对 Steam Deck 控制器界面的初步支持,对于 Steam Deck 控制器手柄,则仅支持简单的输入和切换到蜥蜴模式(Valve 硬件 kb/m 仿真模式);第二批补丁则提供了震感和力反馈,除此之外不支持任何高级功能。

目前 Steam Deck 控制器的初始支持补丁已收入内核 HID 子系统的 for-next 分支,一周后打开的 Linux 6.3 合并窗口将会对这些补丁进行审查和测试。如果顺利合并,则 Linux 内核和所有下游系统都可以启用该 Steam Deck 控制器接口。

GitHub CEO Thomas Dohmke 近日在布鲁塞尔举行的欧盟开源政策峰会上对欧盟即将出台的 AI 法案 (Artificial Intelligence Act) 发表了看法称,开源开发者应该免于此法案的约束,并强调了开源在欧洲 AI 发展中的重要性。

欧盟 AI 法案在 2021 年 4 月被首次提出,由欧盟理事会于去年 12 月 6 日正式批准,预计最早将于今年 3 月由欧洲议会审议;其旨在促进创新,并为 AI 技术设定一个全球标准。一位负责 AI 法案的立法者表示,欧盟立法者希望在下个月就 AI 规则草案达成一致,目标是在年底前与欧盟国家达成协议。

一旦通过,这将是全球首个此类法案。该法案划分了“不可接受风险的应用程序和系统、高风险应用程序、未明确禁止或列为高风险的应用程序”三个风险类别,并根据相应的风险等级制度来监管 AI 应用程序、产品和服务。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Thomas 在峰会上指出,开源为政府和企业提供动力,是”欧洲价值观的核心”,开源正在构建欧洲 AI 的基础。立法者应该对开源开发者放宽约束,因为开源正在推动”全世界和欧洲的创新之春”。

OSS开发人员将共同使用人工智能来帮助改善我们的生活。我毫不怀疑,OSS 开发人员将帮助构建人工智能创新,为残障人士赋能,帮助我们解决气候变化问题,并拯救生命。

因此,虽然该政策可以很好地为世界如何监管 AI 树立先例,但它必须考虑到对开源社区的公平和平衡。作为一个生活在美国的欧洲人,他希望自己可以看到通过开源的 AI 创新,打破只有美国和中国才能在科技创新上领先的说法。

开源社区不是实体社区。这是一个由人组成的社区,合规负担应该落在实体身上,应该落在运输产品的公司身上。OSS 开发人员通常只是志愿者,他们中的许多人同时从事两份工作。他们既是爱好者又是科学家,既是学者又是医生,既是教授又是大学生,他们通常不会从自己的贡献中获利。他们当然没有大笔预算,也没有自己的合规部门。

美国著名智库布鲁金斯学会也曾在去年指出,考虑到个人可能承担的责任风险,新的 AI 法案可能会促使开发人员减少开源模型发布,从而导致 AI 发展将由私营大公司推动。“专有的代码很难分析和构建,这意味着创新将受到阻碍。”

Blender 开发团队宣布已完成将代码托管平台从 Phabricator 迁移到 Gitea 的工作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Blender 代码仓库地址:https://projects.blender.org/blender

Phabricator 最初是 Facebook 内部使用的开发工具,核心开发者是 Evan Priestley,他在离开 Facebook 后,在名为 Phacility 的新公司继续 Phabricator 的开发。2021年5月29日,Phacility 宣布其将停止运营并不再继续维护 Phabricator。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在 Phabricator 宣布停止开发后,Blender 团队便开始寻找替代方案,最后他们选择了 Gitea,任务是将 Blender 整整 20 年的开发历史迁移到这个新的基于 Git 的代码托管平台。

团队介绍道,projects.blender.org 是集错误报告、任务管理和代码 review 一体的新平台:

  • 错误报告和设计任务已迁移至 projects.blender.org,其中包括任务状态、优先级、标签和订阅者。
  • 用户帐户已迁移至 Blender ID。如果你有一个 Blender ID 帐户,用户名现在设置为配置文件中对应的名称。如果没有,则会创建一个新的 Blender ID 帐户。
  • 代码 review 和粘贴尚未迁移但已存档。待处理的代码 review 需要作为 PR 重新提交。
  • 工作板和项目描述将由模块手动重新创建。

据介绍,在正式上线之前,新平台的性能和响应能力比较糟糕,尤其是处理并发请求和执行密集型操作(例如创建 PR)的场景。基于此,Blender 团队对新平台进行了性能优化:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这几天 AI 领域热度不减、新闻层出不穷 —— Google 公布了 Bard、微软将 AI 集成进必应搜索和 Edge 浏览器、百度也公布类 ChatGPT 项目文心一言,近日 LAION 也开源了一个类 ChatGPT 项目 —— Open Assistant。

LAION 是一个德国非营利组织,这个名字你可能不太熟悉,但 Stable Diffusion 和 Imagen 这两个知名的「文本转图像」模型所使用的训练数据集就来自于 LAION,而该组织的目标就是「向公众提供大规模机器学习模型、数据集和相关代码」。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

LAION 开发的类 ChatGPT 项目名为 Open-Assistant,这是一个 AI 聊天机器人项目,能够理解自然语言问题,可以与第三方系统交互并动态检索相关信息。该项目代码是用 Python 编写的,并在 Apache 2.0 许可下发布。

官方在项目愿景中写道:

我们不会止步于复制 ChatGPT。我们希望建立未来的助手,不仅能够写电子邮件和求职信,而且能够做有意义的工作,使用 API、动态研究信息等,并能够由任何人进行个性化定制和扩展。我们希望以一种开放和可访问的方式做到这一点,这意味着我们不仅要建立一个伟大的 AI 助手,而且要使它足够小和高效,能够在消费者硬件上运行。

正如开源项目 Stable Diffusion 的诞生,催生出了一大批文本转图像工具,预计 Open-Assistant 也同样会影响内容生成和自然语言查询的发展。

Open-Assistant 目前还处于研发的初期阶段,将会使用一个公开的语言模型和大量的数据集进行训练(训练数据也会公开),并正在参照现有研究将 RLHF 应用在大型语言模型中。

在未来,为了提高系统的效率,避免必须存储数十亿的预定义参数,该项目将使用一个动态更新的知识库,能够通过搜索引擎检索所需的信息。该项目还将提供工具,允许不受限制地使用准备好的模型,根据自己的喜好进行开发,并在其基础上创建应用程序和服务。

项目地址:https://github.com/LAION-AI/Open-Assistant

摘要:对云端用户而言,业务价值发现是最重要的,华为MRS支持LakeFormation后,成功降低了数据应用的成本,帮助客户落地“存”与“算”的管理,加快推进了数智融合进程,更大程度地释放业务数据价值。

本文分享自华为云社区《华为云MRS支持lakeformation能力,打造一站式湖仓,释放数据价值》,作者:breakDawn。

1 背景

1.1 数仓和数据湖的概念

数据分析技术在2010~2019年间,以湖仓两层架构技术作为主流被各数据厂商所应用,即大数据数仓+数据湖的技术形式。

  • 大数据数仓:出现最早,也最完备,从单机向分布式、智能化发展。例如 Hive、华为DWS等
  • 数据湖:狭义上的湖主要是云厂商参与,以统一的对象存储底座结合云平台水平扩展的计算资源,让分析以数据为本、让业务快起来。

1.2 传统湖仓技术的挑战

以上技术在多年的实践中,逐步衍生出了以下的一些挑战:

  • 随着数据和AI业务持续创新,跨集群、跨服务的数据分析成为普遍需求。然而各集群、各服务各自持有数据,难共享,难维持一致,需要数据ETL操作才能共享。
  • 数据湖、数仓、AI数据化,导致数据虽然可以统一存储在OBS孤岛,但各服务数据独自管理,形成数据管理的孤岛。
  • 湖仓协同仅能通过外表来访问,数据、认证、权限都不能统一配置和管理,尤其是权限不统一严重阻碍了数据跨引擎共享。

上述问题导致了构建、保护和管理数据湖的过程复杂且耗时,通常需要大量开发和维护成本,解决这一问题的关键在于引擎数据需要互通,只有构建满足各种引擎需求的数据湖统一数据服务视图,才能实现数据共享避免其中额外的ETL成本以及降低链路的延时。

1.3 湖仓一体架构的出现

为了解决上述数据湖的相关挑战,2019年左右,业界开始出现一种新的数据架构,叫做DataLakehouse(湖仓一体),它同时吸收了数据仓库和数据湖的优势,能够在存算分离的基础上,构建统一数据层,上层服务通过统一数据层,便捷高效地共享数据和权限管理。因此数据分析师和数据科学家可以在同一个数据存储中对数据进行操作,为公司进行数据治理带来更多的便利性。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2 华为lakeFormation服务关键能力

华为LakeFormation是企业级的一站式湖仓构建服务,提供了数据湖数据统一管理的可视化界面及API,兼容Hive数据模型以及Ranger权限模型,支持无缝对接多种计算引擎(Hive、Spark等)及大数据云服务(MRS、DLI等),使客户便捷高效地构建数据湖和运营相关业务,加速释放业务数据价值,是数智融合的关键基础设施。该产品具有以下关键能力:

  • 丰富的数据和数据权限管理

华为lakeformation支持Catalog和跨源管理,以及库/表/函数的集中管理,可解决多种不同数据类型之间互有差异的痛点,无需再引入第三方ETL进行查看和管理,并实现了统一的细粒度数据权限管理,支持跨服务/跨集群的数据共享。

  • 生态开放

华为LakeFormation兼容社区接口、支持平滑对接和迁移,提供了兼容Hive/Spark/Flink/Trino社区的数据接口,支持计算引擎平滑对接,同时兼容Ranger的权限接口,支持一次授权,统一生效。

  • 大规模、高可靠

华为LakeFormation支持处理海量数据业务,具有百万级超大规模数据管理能力,以及多AZ的容灾能力,可为业务持续性提供稳定保障,且采用Serverless架构,开箱即用,简单易上手。

3 华为云MRS支持lakeformation创造数据价值

3.1 Lakeformation给MRS带来的场景价值

以数智融合场景为例,当大数据用户在MRS中创建了表T1时, 数仓用户可通过lakeformation观察到表T1的数据,并通过DWS写入正确的数据内容。

当AI用户希望通过华为ModelArts读取T1数据时,可借助lakeformation查看T1表,再进行T1数据的获取,整个过程中减少了MRS和其他产品联合协同运作时的复杂ETL操作,大大提升了数据使用的效率。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

另外,当企业用户的安全管理员希望对不同MRS集群中同一业务类型的数据进行ranger权限限制时,可通过lakeformation按下图所示的步骤进行操作,整个过程一次授权,统一生效,充分提高了管理效率,简化管理流程。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

3.2 MRS服务对接lakeformation能力展示

华为MRS用户可基于最新上线的LakeFormation数据连接能力,实现lakeformation实例的创建和授权。

在MRS控制台的数据连接页面,支持创建如下图所示的lakeformation数据连接:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

建立完成lakeformation数据连接后,即可在MRS集群概览中,配置该数据连接,实现MRS和lakeformation之间的数据关联。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

后续再根据产品资料指导完成MRS集群组件相关配置后, 即可正常使用LakeFormation统一的数据湖数据及权限管理,实现数据的管理互通、统一赋权,根据统一的数据进行业务作业提交等。

当用户在lakeformation中针对MRS集群的catalog建立了department表后

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

其他用户可在对应MRS集群的hive客户端中观察这个department表的数据。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

反过来,用户通过MRS的hive客户端创建一个employe表后,可以在lakeformation中看到该数据信息。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

另外也可通过数据权限能力,修改数据表的权限策略,并直接同步到MRS的权限管理组件中。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

4 总结

对云端用户而言,业务价值发现是最重要的,华为MRS支持LakeFormation后,成功降低了数据应用的成本,帮助客户落地“存”与“算”的管理,加快推进了数智融合进程,更大程度地释放业务数据价值。

 

关注,第一时间了解华为云新鲜技术~

本文内容整理自 「智能媒体生产」系列课程第一讲:概念、原理和基本使用,由阿里云视频云媒体服务技术负责人分享智能媒体生产的领域与定位、构架与服务层次、基本概念与技术原理,以及如何一站式开发接入视频制作业务。课程回放视频见文末。

“超视频化”时代,云计算打破产业原有壁垒,推动技术演进发生。媒体生产制作的云端一体服务,为整个泛视频产业带来新的变革,而「智能媒体生产」就是聚焦这一领域的企业级视频制作工具

01 剪辑:核心且有生命力

智能媒体生产在视频生产与消费过程中处于什么位置?从全链路看,视频从采集开始,历经生产制作、管理、分发和消费,而生产制作处于「制播」流程中「制」这个环节

视频生产与消费也发生了趋势上的转变。以生产制作为例,从只有专业人员使用专业的软件,使用非编、转播车工具才能进行制作,到越来越多的人可以在移动端使用一键美颜,在Web端使用各种剪辑工具进行内容生产。

从人工制作到AI全面参与,从专业、小众的制作团队,到普罗大众,从被动接收到个性互动,在趋势的变化过程中,互联网和云计算起到了至关重要的作用。而云上生产制作,就是智能媒体生产服务的领域

生产制作,在视频全链路中的比重将会增加,主要基于两点:一是短视频APP的兴起,让普通老百姓的美学素养有了普遍提升;二是真正优质的内容仍较少,内容的质量以及分发的效率成为各方角逐的焦点。从这两个维度来看,智能媒体生产服务发挥的空间也将有所提升。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

智能媒体生产解决什么问题?

云计算浪潮之下,云上生产制作演变为业务面临的主要场景,而智能媒体生产着力解决其中六大问题。

l 云端剪辑制作合成。智能媒体生产解决的第一个核心问题就是如何在云端实现高效快速的剪辑、制作、合成导出。

l 素材库管理与公共素材的使用。云上生产制作面临着大量素材管理的问题,以及当缺少素材时,需要系统提供公共素材供用户使用。

l 规模化剪辑制作合成。在满足剪辑制作和素材管理的基本需求后,业务可能需要快速生产规模化视频,由于视频创作过程较为繁琐,规模化的制作能够极大地提高生产效率。

l 专业、高效剪辑制作合成。云端生产制作之前,存在大量专业非编工具,非编工具有其优点,也存在一些劣势,比如本地渲染会消耗大量资源,占用客户端时效,客户需要大量等待时间才能够得到成片,而智能媒体生产正是解决如何在云端专业、高效发挥作用这一问题。

l AI辅助生产制作。随着AI在各个领域的深入,是否能够引入AI,进一步提升生产制作效率,解决制作周期长的问题,成为智能媒体生产关注的问题。

l 无干预的全智能生产制作。客户的诉求通常是很发散的,比如需要制作某种主题的视频,但是该主题对应的素材以及如何编排仍未确定,这时则存在一种高阶的生产制作需求:在无干预的状态下,由云上生产制作系统进行一键式全智能生产制作。

剪辑

剪辑是智能媒体生产的核心。什么是剪辑?引用世界剪辑大师沃尔特·默奇的话,剪辑是在两个空间维度和一个时间维度对声音和画面做马赛克式的拼接。剪辑实际上是一次创作的过程,既包括对时间轴的处理,也包括对视频画面的处理、音频的处理。

完美的剪辑需要满足六项准则,按顺序,分别是剪辑的情感,故事性,剪辑编排的节奏,视线的走向,二维特性以及三维立体的连贯性。剪辑的核心关键点在于何时、何处将一个画面转向另一个画面。

为了更好地服务云上生产制作的客户,智能媒体生产服务解构出五种能力:

第一,提供大量的素材;

第二,提供多样化工具;

第三,能够高效地对视频素材画面进行解构,便于后续时间线的编排;

第四,在剪辑交互操作过程中,引入丰富的视觉和音频效果;

第五,整体的剪辑是连贯,一气呵成的。

基于此,设计有生命力的生产制作流程,成为视频智能媒体服务需要考虑的重点

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

02 云端一体,协同运转

工作流程

智能媒体生产的流程可以分为三个部分。

输入部分的核心是内容资源库的管理和设计,既包括丰富的来源,也拥有多样化的文件类型,其中包含传统的音视图文等媒资,也包含更泛化的数据、富文本和故事板等类型。

输出的成片以及媒体内容,也可以反过来回溯到输入部分,作为下一次创作素材的补充。

素材经过媒体预处理的环节,从视觉、声音、文本等多个维度进行智能分析与处理,输出针对视频画面和声音的解构,用于创作者结合不同场景创作工具进行思路创作。

其中,既包括移动端的创作工具,又包括Web端的剪辑工具,还有基于云端的模板工厂和AI辅助的规模化、批量化生产制作工具。

生产制作部分,列举了剪辑制作的各种能力,既有简单的剪切拼接,也有多轨的图像叠加和混音、图文混编,叠加智能能力的字幕、配音、集锦以及综合制作。

影像内容消费实际上是智能媒体生产制作的输出渠道,既可以输出直接用于分发的成片,可二创的素材,同时还可以输出非视频文件的故事板,用于线下精编进行二次加工,而消费体验反馈又会回到智能制作系统的AI算法侧,促进AI的自学习。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

技术架构

智能媒体生产的技术架构,从下往上看,最底侧是媒体生产所依赖的媒资库,包括音视图文数据,文件与实时流,模版,制作工程以及临时媒资文件,同时还包括以特征值为主的人物、标签、版权和镜头等类型。

中间是媒体生产的核心架构模块,可分成生产工具和生产制作服务两大模块,并通过API进行桥接。生产工具方面,主要是故事板、效果编辑和播放器三个组件,底层的内核是预览的渲染引擎。

生产制作服务方面也分为三个核心模块:最底层渲染合成的剪辑制作模块,时间线纠错和补全的处理中心,以及用于规模化、批量化生产的模板工厂。

关于时间线,时间线既支持人工组织,也支持AI辅助组织,而AI辅助组织时间线依赖于很多原子AI算法能力。

再往上两个层次分别是SaaS各种服务/页面,以及不同的生产制作场景,以上构成了智能媒体生产的技术架构。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

服务层次

智能媒体生产的服务层次,是提供云端一体、可分可合的PaaS云服务和PaaS+的WebSDK。

如何理解云端一体?云端一体就是云跟端在协议和顶层设计上进行一体化设计,所有云服务提供的能力都可以由端上的WebSDK提供,端侧的WebSDK最终所指向调用的云端服务,跟通过API调用是一模一样的。

可分可合的意思是可以单独地使用WebSDK,或者单独地使用云服务而不受影响

先看云服务,云服务的核心是通过OpenAPI提供服务,最后剪辑制作任务完成的通知靠事件通知工具来回调。

整个OpenAPI分成四大板块,一是剪辑制作,是最核心的板块,包括标准剪辑,直播剪辑,以及更复杂的云剪辑工程管理。二是媒资库,即关于素材库以及输出成片的管理。三是智能任务,在剪辑制作过程中发挥辅助的API作用。四是模板工厂,主要提供批量化、规模化降低门槛服务,而公共配置实际上是为事件通知服务的。

云服务板块与上面的WebSDK一脉相承。 WebSDK提供的核心场景能力有三种,分别为标准剪辑,直播剪辑和模板工厂剪辑。

标准剪辑主要涉及资源和交互两个门类,资源即各种轨道、素材、滤镜、转场、特效等效果,交互即提供各种剪辑操作方面的交互模式。

直播剪辑也是如此,不同的是,直播剪辑操作的资源是直播流,交互则采用了双播放器以及单轨剪辑模式。

模板工厂剪辑的资源跟标准剪辑相同,但是交互存在一些区别,可以根据时间线的固定部分创建模板,然后将模板中可替换的素材或者是非素材部分进行参数覆盖。

WebSDK公共的两大子组件,分别是时间线和剪辑播放器,时间线目前支持多轨、多素材和多种效果,按照创意思路进行编排,与传统播放器相比,剪辑播放器除了支持List播放以及时间线效果预览之外,还需要将素材叠加各种效果进行单视频播放。

WebSDK逻辑兼顾交互逻辑和UI,自带CSS样式,客户可以通过简单的十几行代码,非常快捷地创建属于自己的剪辑交互界面

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

03 技术原理与设计实现

基本概念

l 素材

素材即用于剪辑制作的原材料,拥有丰富的类型,如视频,纯音频,图片,独立字幕等,也可以是泛文本,或者是逻辑的设计实体。

l 时间线

时间线是智能媒体生产最核心的概念,是音视图文多层轨道,多个素材,多类效果,按照视频创作思路编排的过程和结果,既描述创作的过程,也描述创作的结果。

同时也是剪辑合成的依据,当把结果提交到云端时,云剪辑的合成服务就会按照时间线最终结果进行渲染和合成,因此,时间线是智能媒体生产最重要的数据结构,也是视频生产制作的核心。

l 模板

模板是把时间线的素材编排规律,包括转场/滤镜/特效的规律,以及其他规律进行抽象,并把其中可以固定的部分进行固定化、标准化的结果。相比时间线,使用模板会更加方便、容易地进行规模化的制作。

l 云剪辑工程

云剪辑工程是一个更大范畴的概念,用于描述一次视频创作过程中所涉及的所有数据,一般包括基本的数据,比如剪辑的标题、创建时间、描述,视频创作所需要的素材,以及描述实际视频创作内容的时间线等。

l 剪辑合成任务

剪辑合成任务是指当视频创作完成之后,可将最终制作好的时间线或者模板提交合成,生成新的媒体资源。媒体资源的合成,是一个异步的过程,剪辑合成任务则描述了任务从开始创建到最终完成的过程。

l 成片

成片是剪辑制作、合成或者导出的目标产物。成片在这里是一个广义的概念,针对当次剪辑的输出,因此,当次的成片也可以作为下次的素材进行二次创作。

l 智能任务

在剪辑制作和合成中,可以对素材或者生成目标媒体资源的过程进行智能处理,智能任务则用来描述对应的智能处理过程。

核心链路与设计原则

l 核心链路

核心链路包含抽象层输入、处理和输出三部分。

输入和输出与泛媒资库有关,其中来源与目标具有一致性,如统一媒资、OSS对象和第三方URL。输入部分增加了对直播流的支持,输出部分则增加了对时间线交换的类型支持。

处理部分,处理的过程实际上就是剪辑、包装、渲染与合成的异步过程,其中最核心的对象是时间线,同时,涉及到的高级管理包括复杂的云剪辑工程管理,素材管理以及成片管理。

此外,提效方式包括三种:模板工厂用于批量化、规模化生产视频;智能生产模式适用于提升人工处理效率的时效性;并行剪辑用于提升长视频或者多素材场景的合成耗时。

l 设计原则

输出部分最核心的设计原则即源文件的输入输出原则

剪辑实际上是为了生产源片,因此,使用的素材也是源文件,不管素材库的素材输出多少路的转码文件,在剪辑合成时使用的也是素材的原始文件,并合成目标成片的原始文件,根据需要转码生成不同清晰度的输出流。

此外,还需要设置三个参数。在没有手动指定的情况下,参数都有默认的策略。

第一个参数关于目标成片的分辨率,默认使用原文件素材的最大宽高。举例说明,存在三个素材,源文件的分辨率分别是三个数值,则会取这三个素材的最大宽作为输出的宽,最大高作为输出的高。

第二个参数关于码率,与上述类似,会取源文件的最大码率作为目标的合成码率,当然也会有一个上限阈值,防止源文件中某一素材的码率特别高,导致输出的成片质量差。

最后一个参数关于格式,在没有指定的情况下,默认采用264的编码和MP4的封装,以及AAC的音频格式。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

媒资库设计

媒资库的设计要点分别是开放性灵活性跨产品协作

开放性体现在两个方面:第一,提供了多租户用户隔离的媒资库,同时开放了大量音乐素材版权给客户进行剪辑使用;第二,媒资库设计为跨产品的融合,本质上也是开放性维度的体现。

在生产制作过程中,并不强侵入性地要求注册媒资,或者使用智能媒体服务的媒资,而是也可以使用视频点播VOD产品的媒资,以及第三方的文件和直播流,三方文件甚至支持S3协议。

媒资库统一了管理范围,以源文件为素材,目标文件为成片,临时的时间线和制作工程也在管理范畴内。

此外,媒资管理是泛媒体的管理,除了传统的音视图文媒资之外,还包括其他通用的媒资管理,都可以纳入到媒资内容素材管理中。媒资库在视频云层面是统一的,拥有统一的数据体系,并且支持自定义。

同时,存储能力可以直接复用OSS的存储和视频点播的存储,媒体处理能力也跟MPS转码的媒体处理能力完全对应,所有可以在MPS上设置的编解码参数,都可以在智能媒体生产体系中完成。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

时间线

时间线的设计核心是“统一”,即统一的架构和统一的协议。

统一的协议是指端跟云使用同一套时间线协议,统一的架构是指云跟端的行为是完全一致的,所有能够在端上操作获得的效果都可以通过API完成。

时间线的设计结合了专业非编和传统EDL的特点。专业非编都是多轨的,素材和效果的设计各异,整个时间线非常复杂和专业,而传统EDL是单轨的,定义素材但不定义效果和舞台,时间线相对比较简单,业界对此并没有统一的标准。

因此,阿里云自己定义了一套时间线协议标准,在云和端采用一体化的可复用设计。

时间线涉及的对象有四类。第一,轨道/图层,其中称音频为Track轨道,而称视频为Layer图层。第二,Clip,素材,素材是铺设在轨道上进行内容编排的最小单位。第三,Effect,效果,效果既可以作用在素材上,也可以作用在轨道上。第四,Scene,舞台,舞台就是最终的画布,剪辑合成的成片所拥有的画布就是舞台。

设计需要有取舍和平衡。 首先,效果轨道可以独立出现,增加了一定的灵活度,其次保留了轨道的素材,原始素材仅作为引用。在专业非编中,轨道素材和原始素材是分别在时间线中多次描述的,导致使用过程比较复杂,而仅仅保留轨道上使用的素材,可以提高其易用性。

同时,按照素材类型做多轨设计,支持画布的自动参数设置和自定义参数设置,保证了时间线的通用性和可扩展性。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

通过时间线数据结构详情,可以看到,时间线的第一级结构是各个轨道,按照类型分为视频、音频、图片、字幕和效果轨道,可进行叠加,并根据轨道内数组的层叠顺序进行渲染,每一个轨道又包含多个素材,即轨道素材,与轨道相对应。

同时,ImageTrack(图片轨道),SubtitleTrack(字幕轨道),EffectTrack(效果轨道)都作用在视觉上,通过最简模式,在调用API时统一设置成VideoTrack,并通过TrackType进行区分,大大降低了开发的工作量

ImageTrack以及图片素材对于最终合成的成片来讲,都可认为是视觉上的素材,仍然可以通过视觉轨道素材的Type区分原始素材类型,进一步减少开发量。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

以下展示多轨道的前端效果,左上角是素材库、内容库,中间是播放器,最右侧是效果的编辑区。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

进一步拆解轨道素材,可列举出8个主要属性。MediaId和MediaURL用于描述具体对应哪个素材,是素材的标识,既支持直接引用媒资库里的媒资Id,也支持指定OSS地址或第三方S3地址。这两个参数有且仅有一个不能为空。

Type是指素材片段类型。In和Out是指素材片段相对于完整素材的入、出点。需要区分TimelineIn和TimelineOut,两者容易混淆,In和Out是指从一段完整的素材里截取的哪一片段,比如,整段素材是十分钟,从第一分钟截取到第二分钟,那么In就是60s,Out就是120s。

TimelineIn和TimelineOut则用于描述素材片段相对于最终输出成片时间线的入、出点。比如,一分钟的素材截取出来用于片尾创作,可能这个片尾已经到了整个时间线的第30分钟和第31分钟了,那么TimelineIn是30分钟,TimelineOut是31分钟。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

关于效果,除了基础的文字,裁剪,贴边或者Scale,还有特效的部分,可分成三类:VFX,是指针对整个画面完整特效的应用;Filter滤镜,是对色彩调和和风格化效果的呈现;Transition转场,一般用于两个素材接缝处。

目前,转场、滤镜和特效总计达到200+种,非常丰富,具体内容可参见官网: https://help.aliyun.com/document_detail/449558.html

同时,支持更细粒度地指定特效的属性,针对特效本身指定其应用在时间线上的入、出点,当特效涉及到视频画面时,还可以进行坐标和宽高的设置。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

模板工厂

模板工厂跟时间线的设计原则非常相似,也是完全云端一致的。模板能力既可以通过Open API调用实现规模化的生产制作,也可以通过WebSDK或者阿里云控制台进行交互操作和提交。

目前,模板工厂已经支持公共模板库和自定义模板,且自定义模板坚持普惠化,与Adobe AE生态打通,通过引入专业的AE模板,让开发者能够非常方便且规模化地生产制作。

相对于时间线,模板的参数简化为两个:一个是模板ID,另一个是关于素材的参数组合,即把时间线里可以固定的部分进行固定化和标准化,把可变的部分做成ClipsParam,然后把结果创建成一个模板ID。

通过模板工厂,能够很方便地降低创意门槛和使用门槛,设计师可以设计好模板,并供调用方调用,同时,模板工厂的模板本身也支持嵌套或者组合使用。

举例说明,有一个标准的完整时间线,主要功能是在视频画面上叠加图片,比如logo,如果只需不停更换视频,可以把图片整体的内容做成模板,把视频的MediaId做成模板中可变的部分,在Template Config里传入video,即传入要进行模板应用的素材,就可以非常方便地实现与时间线相同的功能。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

此外,还可以使用高级模板将专业制作能力进行规模化量产。高级模板完美结合Adobe设计师生态,并内置了70+官网模板,同时,支持使用Adobe AE制作视频,通过插件导出到模板工厂进行模板注册,以及支持模板工厂服务器批量生成视频,更多详细内容可参考以下文档。

高级模板制作流程: https://help.aliyun.com/document_detail/467970.html

高级模板设计规范: https://help.aliyun.com/document_detail/467972.html

高级模板API调用详解: https://help.aliyun.com/document_detail/445389.html

高级模板的效果如下,通过应用专业模板效果,可以将几张原始的图片素材生成最终的炫酷视频: https://v.youku.com/v_show/id_XNTk0MjA3OTg1Ng==.html

04 动手实操,一站式开发接入

智能媒体生产服务最核心的是剪辑制作与合成。作为一站式开发的主链路,剪辑制作与合成实际上是一个异步处理的过程,核心是提交任务,接收回调和查询任务状态,获得合成结果,共包含三个辅助子场景,媒资管理,智能任务处理以及全局配置。

关于剪辑合成任务的处理共有三种调用方式:第一种是直接调用OpenAPI发起任务;第二种是通过阿里云IMS控制台发起调用;第三种是在自己的业务系统中集成剪辑WebSDK发起调用。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

以下介绍若干流程,其中前面几个流程都是直接通过OpenAPI的方式发起剪辑合成任务,并且获取结果。

Timeline剪辑合成

使用Timeline直接进行剪辑合成是最简流程,通过组织参数,由客户直接调用OpenAPI发起剪辑合成任务,核心参数是Timeline时间线这个字段,同时设置合成的目标,比如宽高、码率,当然也可以不设置,只需设置合成目标的路径。

虽然剪辑合成的链路是异步的,但是提交作业是个同步服务,会同步返回三个核心参数。第一个是代表此次合成任务的JobId,即作业Id。第二个是提交时间线内容时创建的云剪辑工程Id,当工程Id没有填写时,会自动进行创建,同步返回ProjectId。第三个字段是默认合成的新成片的Id,提前返回给提交方。

提交方提交任务之后处于等待结果的状态,共有三种方式接收结果:

第一种是通过回调服务,主动接收事件通知,即在合成完成后主动向配置了回调服务地址的客户发送回调,回调支持HTTP回调和MNS回调两种,效率较高。

其他两种方式由客户调用方发起查询。一种查询方式通过作业ID,查询合成任务的状态和相关信息;另一种方式更关心合成的媒资成片的信息,通过MediaId直接查询相媒资内容信息,即GetMediaInfo。

基于效率考虑,推荐使用第一种回调服务的方式,即主动接收发送的回调。客户方发起查询的方式,需要不停地建立轮询的请求。

当然也可以两种方式相结合,比如,默认以回调服务接收,如果超过了客户侧设置的时间,也可以通过调用查询服务主动获取相关状态。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

标准模板剪辑合成

标准模板剪辑合成与使用Timeline剪辑合成非常相似,唯一不同的是提交的参数。

可以看到,提交的API服务的名字、返回的字段、回调的方式和查询的方式都是一样的,而提交的参数由Timeline变成了模板的两个核心参数,一个是模板ID(TemplateId),另外一个是素材的覆盖参数(ClipsParam)。使用该接口的前提是已经自定义了模板工厂的模板,或者直接使用公共模板库中系统自带的模板。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

高级模板剪辑合成

高级模板意味着要使用Adobe After Effect制作AE模板来发起合成,核心参数与标准模板相同,但在提交高级模板合成之前,有两个额外的步骤。

一是需要先在本地下载并安装AE和VE Exporter插件。

二是基于AE创作,使用VE插件导出模板以及相应素材,打包成包含模板工程信息以及素材信息的zip文件,上传至OSS,然后提交模板合成。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

直播剪辑

直播剪辑场景的核心参数略有一些变化,因为直播剪辑的输入源是直播流。目前我们支持针对多个直播流的直播素材进行剪辑,因此,除了指定素材本身,还需要额外指定直播流的配置。

直播剪辑有两种模式,一种是粗剪,粗剪是TS精度的,最快时效为秒级。另一种是精剪,达到准帧精度,通过优化,直播剪辑的时效性可以达到20倍速。

直播剪辑可以在两种场景下使用。一是直播结束之后,对直转点内容进行剪辑,直转点的内容源头需要是阿里云的直播流。二是在直播的进行过程中,对已直播过的内容进行快速剪辑。

同时,直播剪辑支持多个直播流的混剪,也就是说,并不限制单个直播流,而是可以把多个直播流的不同素材片段一起进行剪辑。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Web工具剪辑合成

使用Web工具进行剪辑并提交合成,共有两种模式,一种是使用阿里云控制台,直接在阿里云控制台上进行操作。

另一种是集成WebSDK,在客户自己的业务页面进行剪辑与提交合成,实现剪辑流程与业务APP或业务系统更紧密的结合。标准剪辑-时间线和标准剪辑-模板,以及直播剪辑都支持在Web端进行剪辑制作和效果预览。

当制作完成后,如果使用的是阿里云控制台,则可以直接在界面上提交合成,因为阿里云控制台理论上其实是一个SaaS,可以直接使用。

如果使用的是集成WebSDK到自己的业务界面,则可以在后端调用SubmitMediaProducingJob(标准剪辑)或者SubmitLiveEditingJob(直播剪辑),只不过Timeline不是人工拼成,而是直接由WebSDK生成的。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

剪辑工程管理与使用工程ID提交合成

剪辑工程管理与使用工程ID提交合成更复杂一些,适用于客户或者开发者对于剪辑工程有更深入诉求,希望对剪辑工程进行深入管理的情况,共有两种方式:

一种方式是创建一个云剪辑工程,并直接指定其时间线数据,通过工程ID进行合成,此方式无需传入时间线,因为工程ID背后的时间线数据,可以从工程对象获取,而提交之后的流程与前面流程保持一致。

另一种方式是先创建一个云剪辑工程,然后不停更新时间线数据,最后仍然通过工程ID提交合成作业,后续流程仍然相同。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

媒资库资源注册

媒资库支持对OSS Object和VOD Media发起注册,注册之后,会生成统一的MediaId方便后续管理和剪辑制作。

实际上VOD的MediaId在后续版本中不再需要手动发起注册,而是将智能媒体服务与VOD进行统一MediaId抽象,也就是说可以天然地识别VOD MediaId,而无需注册成IMS MediaId,当然,强行把VOD MediaId注册成IMS MediaId也是可行的。

此外,媒资库的开放性意味着媒资注册并不一定要显示调用

提交剪辑合成时,Timeline轨道里的素材可以直接传入媒体URL,而无需事先注册,并且支持提交合成之后将未注册的素材自动进行注册。MediaId统一之后,反过来也意味着,智能媒体服务的生产工具IMS也可以看作VOD的生产制作工具,直接给VOD剪辑使用。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

智能任务处理

智能任务处理在素材分析、剪辑与包装阶段进行智能分析或处理。智能任务的分析是一个耗时的过程,所以需要先提交任务,再通过作业ID进行查询。

智能任务,可分为两大类,SummitASRJob和SummitAudioProduceJob,这两个作业一般作为生产制作过程中的素材辅助信息或素材中间信息,任务的提交结果需要与时间线编排和制作结合起来,完成最终的创作与成品合成。

而SummitIProductionJob的输出结果已经是封面、摘要,或者擦除logo、文本之后的视频,因此,作业结果一般可以直接作为成片输出,并通过JobId主动查询获取。任务的执行方式仍然是异步的过程,而智能任务在生产制作中起到辅助提效的作用。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

本次课程希望能够让大家对智能媒体生产有基本的概念,更多的样例和实践可参见官网文档: https://help.aliyun.com/product/193643.html

更多完整内容详见课程回放 ⬇️ https://v.youku.com/v_show/id_XNTk0MjA3OTg1Ng==.html

摘要:在业务功能实现时,经常会用到视图简化查询SQL。但有时候会因为视图降低查询效率,本文主要分析在业务需求满足的情况下,将有效的过滤条件传递到基表,减少运算过程中数据库需要处理的数据量,提升SQL执行效率。

本文分享自华为云社区《GaussDB(DWS)业务视图优化-过滤条件传递》,作者:卫小毛 。

在业务功能实现时,经常会用到视图简化查询SQL。但有时候会因为视图降低查询效率,本文主要分析在业务需求满足的情况下,将有效的过滤条件传递到基表,减少运算过程中数据库需要处理的数据量,提升SQL执行效率。

SQL举例


sql 分析:以上SQL vw_pay_voucher_bill t2 、xact_hi_taskinst t1 视图和表进行关联查询

根据业务特性分析过滤效果较好的字段为 agency_id

优化前耗时: 22s

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

分析执行计划:

时间主要耗时在 seq scan on pay_voucher_bill v 这一步

看到该表过滤条件仅有mof_div_code、fiscal_year、is_deleted 过滤效果差,几乎全表数据参与过程运算,执行代价高

视图及表结构分析

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

视图中关联条件较为有效的过滤条件,bgt_id 字段查询时不会应用。分析视图中“v”和“t”表都存在agency_id 字段,当前t表过滤使用了agency_id字段,可以考虑视图定义中量表关联条件增加 agency_id 字段关联条件需要考虑业务需求。

同业务沟通后可进行优化

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

优化后耗时:0.4s

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

对比优化前后SQL查询结果一致

优化总结:

同业务侧研发沟通客户实际需要仅需要查询本单位 (agency_id) 下的数据,但因为SQL和视图设计时,并未将这一有效条件传递给每张表。导致数据库在针对 pay_voucher 进行数据过滤时需要将全表64万+ 数据筛选出来进行运算,仅仅这一步开销就占用了20s+。在优化后(视图中增加agency_id关联信息后,该操作可将agency_id 过滤条件传递给基表 pay_voucher),仅需从pay_voucher 表中获取738行数据进行运算,最终sql耗时降为 0.4s左右。

 

关注,第一时间了解华为云新鲜技术~

一、Master高可用架构

Kubernetes作为容器集群系统,通过健康检查+重启策略实现了Pod故障自我修复能力,通过调度算法实现将Pod分布式部署,并保持预期副本数,根据Node失效状态自动在其他Node拉起Pod,实现了应用层的高可用性。

针对Kubernetes集群,高可用性还应包含以下两个层面的考虑:Etcd数据库的高可用性和Kubernetes Master组件的高可用性。 而Etcd我们已经采用3个节点组建集群实现高可用,本节将对Master节点高可用进行说明和实施。

Master节点扮演着总控中心的角色,通过不断与工作节点上的Kubelet和kube-proxy进行通信来维护整个集群的健康工作状态。如果Master节点故障,将无法使用kubectl工具或者API做任何集群管理。

Master节点主要有三个服务kube-apiserver、kube-controller-manager和kube-scheduler,其中kube-controller-manager和kube-scheduler组件自身通过选择机制已经实现了高可用,所以Master高可用主要针对kube-apiserver组件,而该组件是以HTTP API提供服务,因此对他高可用与Web服务器类似,增加负载均衡器对其负载均衡即可,并且可水平扩容。

多Master架构图:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

二、部署Master2 Node

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

现在需要再增加一台新服务器,作为Master2 Node,IP是192.168.2.117。

Master2 与已部署的Master1所有操作一致。所以我们只需将Master1所有K8s文件拷贝过来,再修改下服务器IP和主机名启动即可。

 

2.1安装 docker


2.2创建etcd证书目录

在Master2创建etcd证书目录:


2.3拷贝文件(Master1操作)

拷贝Master1(119)上所有K8s文件和etcd证书到Master2(117):

scp -r /opt/kubernetes root@192.168.2.117:/opt scp -r /opt/etcd/ssl root@192.168.2.117:/opt/etcd scp /usr/lib/systemd/system/kube* root@192.168.2.117:/usr/lib/systemd/system scp /usr/bin/kubectl  root@192.168.2.117:/usr/bin scp -r ~/.kube root@192.168.2.117:~

2.4删除证书文件

删除kubelet证书和kubeconfig文件


2.5修改配置文件IP和主机名

修改apiserver、kubelet和kube-proxy配置文件为本地IP


2.6设置开机启动


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.7批准kubelet证书申请


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

三、部署Nginx+Keepalived高可用负载均衡器

kube-apiserver高可用架构图:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

• Nginx是一个主流Web服务和反向代理服务器,这里用四层实现对apiserver实现负载均衡。

• Keepalived是一个主流高可用软件,基于VIP绑定实现服务器双机热备,在上述拓扑中,Keepalived主要根据Nginx运行状态判断是否需要故障转移(漂移VIP),例如当Nginx主节点挂掉,VIP会自动绑定在Nginx备节点,从而保证VIP一直可用,实现Nginx高可用。

注1:独立于k8s集群之外部署,只要nginx与apiserver能通信就行。

注2:如果你是在公有云上,一般都不支持keepalived,那么你可以直接用它们的负载均衡器产品,直接负载均衡多台Master kube-apiserver,架构与上面一样。

在两台Master节点操作。

 

2.1安装软件包(主/备)


2.2Nginx配置文件(主/备一样)


2.3 keepalived配置文件(Nginx Master)

cat > /etc/keepalived/keepalived.conf << EOF global_defs {     notification_email {       acassen@firewall.loc       failover@firewall.loc       sysadmin@firewall.loc     }     notification_email_from Alexandre.Cassen@firewall.loc      smtp_server 127.0.0.1     smtp_connect_timeout 30     router_id NGINX_MASTER }  vrrp_script check_nginx {     script “/etc/keepalived/check_nginx.sh” } vrrp_instance VI_1 {      state MASTER      interface ens192  # 修改为实际网卡名     virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的      priority 100    # 优先级,备服务器设置 90      advert_int 1    # 指定VRRP 心跳包通告间隔时间,默认1秒      authentication {          auth_type PASS               auth_pass 1111      }       # 虚拟IP     virtual_ipaddress {          192.168.2.88/24     }      # 执行脚本     track_script {         check_nginx     }  } EOF

  • vrrp_script:指定检查nginx工作状态脚本(根据nginx状态判断是否故障转移)
  • virtual_ipaddress:虚拟IP(VIP)

准备上述配置文件中检查nginx运行状态的脚本:


2.4 keepalived配置文件(Nginx Backup)


准备上述配置文件中检查nginx运行状态的脚本:


注:keepalived根据脚本返回状态码(0为工作正常,非0不正常)判断是否故障转移。

检查节点状态:

a42ac15ac8f826f705623c1293a160b7.png

2.5 启动并设置开机启动


2.6 查看keepalived工作状态

虚拟VIP绑定到 Nnginx服务器,  88 虚拟IP是 Nginx 服务器使用的IP,nginx 会帮助我们 将请求转发到 APIServer。

588a501b2801c134b9f27d3c79294270.png

2.7 Nginx+Keepalived高可用测试

关闭主节点Nginx,测试VIP是否漂移到备节点服务器。

在Nginx Master执行 pkill nginx;
在Nginx Backup,ip addr命令查看已成功绑定VIP。

2.8 访问负载均衡器测试

找K8s集群中任意一个节点,使用curl查看K8s版本测试,使用VIP访问:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

可以正确获取到K8s版本信息,说明负载均衡器搭建正常。该请求数据流程:curl -> vip(nginx) -> apiserver

通过查看Nginx日志也可以看到转发apiserver IP:

[root@k8s-master1 ~]# tail -2f /var/log/nginx/k8s-access.log

192.168.2.118 192.168.2.119:6443 – [30/Oct/2022:13:00:44 +0800] 200 287

192.168.2.117 192.168.2.117:6443 – [30/Oct/2022:13:00:44 +0800] 200 287

192.168.2.117 192.168.2.119:6443 – [30/Oct/2022:13:00:44 +0800] 200 287

192.168.2.119 192.168.2.117:6443 – [30/Oct/2022:13:00:44 +0800] 200 287

192.168.2.210 192.168.2.119:6443 – [30/Oct/2022:13:00:45 +0800] 200 287

192.168.2.118 192.168.2.117:6443 – [30/Oct/2022:13:00:45 +0800] 200 287

192.168.2.117 192.168.2.119:6443 – [30/Oct/2022:13:00:45 +0800] 200 287

2.9 修改所有Worker Node连接LB VIP

试想下,虽然我们增加了Master2 Node和负载均衡器,但是我们是从单Master架构扩容的,也就是说目前所有的Worker Node组件连接都还是Master1 Node,如果不改为连接VIP走负载均衡器,那么Master还是单点故障。

因此接下来就是要改所有Worker Node(kubectl get node命令查看到的节点)组件配置文件,由原来192.168.2.119修改为192.168.2.88(VIP)。

在所有Worker Node执行:


检查节点状态:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



 

Transformer 模型是 AI 系统的基础。已经有了数不清的关于 “Transformer 如何工作” 的核心结构图表。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

但是这些图表没有提供任何直观的计算该模型的框架表示。当研究者对于 Transformer 如何工作抱有兴趣时,直观的获取他运行的机制变得十分有用。

Thinking Like Transformers 这篇论文中提出了 transformer 类的计算框架,这个框架直接计算和模仿 Transformer 计算。使用 RASP 编程语言,使每个程序编译成一个特殊的 Transformer。

在这篇博客中,我用 Python 复现了 RASP 的变体 (RASPy)。该语言大致与原始版本相当,但是多了一些我认为很有趣的变化。通过这些语言,作者 Gail Weiss 的工作,提供了一套具有挑战性的有趣且正确的方式可以帮助了解其工作原理。


在说起语言本身前,让我们先看一个例子,看看用 Transformers 编码是什么样的。这是一些计算翻转的代码,即反向输入序列。代码本身用两个 Transformer 层应用 attention 和数学计算到达这个结果。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

文章目录

  • 第一部分:Transformers 作为代码
  • 第二部分:用 Transformers 编写程序

Transformers 作为代码

我们的目标是定义一套计算形式来最小化 Transformers 的表达。我们将通过类比,描述每个语言构造及其在 Transformers 中的对应。(正式语言规范请在本文底部查看论文全文链接)。

这个语言的核心单是将一个序列转换成相同长度的另一个序列的序列操作。我后面将其称之为 transforms。

输入

在一个 Transformer 中,基本层是一个模型的前馈输入。这个输入通常包含原始的 token 和位置信息。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在代码中,tokens 的特征表示最简单的 transform,它返回经过模型的 tokens,默认输入序列是 “hello”:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如果我们想要改变 transform 里的输入,我们使用输入方法进行传值。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

作为 Transformers,我们不能直接接受这些序列的位置。但是为了模拟位置嵌入,我们可以获取位置的索引:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

前馈网络

经过输入层后,我们到达了前馈网络层。在 Transformer 中,这一步可以对于序列的每一个素独立的应用数学运算。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在代码中,我们通过在 transforms 上计算表示这一步。在每一个序列的素中都会进行独立的数学运算。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

结果是一个新的 transform,一旦重构新的输入就会按照重构方式计算:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

该运算可以组合多个 Transforms,举个例子,以上述的 token 和 indices 为例,这里可以类别 Transformer 可以跟踪多个片段信息:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们提供了一些辅助函数让写 transforms 变得更简单,举例来说, 提供了一个类似 功能的结构。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

使我们可以定义自己的操作,例如一个字符串以 转换。(用户应谨慎使用可以使用的简单神经网络计算的操作)


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

函数 (functions) 可以容易的描述这些 transforms 的级联。举例来说,下面是应用了 where 和 atoi 和加 2 的操作


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

注意力筛选器

到开始应用注意力机制事情就变得开始有趣起来了。这将允许序列间的不同素进行信息交换。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们开始定义 key 和 query 的概念,Keys 和 Queries 可以直接从上面的 transforms 创建。举个例子,如果我们想要定义一个 key 我们称作 。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

对于 也一样


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

标量可以作为 或 使用,他们会广播到基础序列的长度。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们创建了筛选器来应用 key 和 query 之间的操作。这对应于一个二进制矩阵,指示每个 query 要关注哪个 key。与 Transformers 不同,这个注意力矩阵未加入权重。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

一些例子:

  • 选择器的匹配位置偏移 1:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • key 早于 query 的选择器:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • key 晚于 query 的选择器:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

选择器可以通过布尔操作合并。比如,这个选择器将 before 和 eq 做合并,我们通过在矩阵中包含一对键和值来显示这一点。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

使用注意力机制

给一个注意力选择器,我们可以提供一个序列值做聚合操作。我们通过累加那些选择器选过的真值做聚合。

(请注意:在原始论文中,他们使用一个平均聚合操作并且展示了一个巧妙的结构,其中平均聚合能够代表总和计算。RASPy 默认情况下使用累加来使其简单化并避免碎片化。实际上,这意味着 raspy 可能低估了所需要的层数。基于平均值的模型可能需要这个层数的两倍)

注意聚合操作使我们能够计算直方图之类的功能。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

视觉上我们遵循图表结构,Query 在左边,Key 在上边,Value 在下面,输出在右边

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

一些注意力机制操作甚至不需要用到输入 token 。举例来说,去计算序列长度,我们创建一个 ” select all ” 的注意力筛选器并且给他赋值。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这里有更多复杂的例子,下面将一步一步展示。(这有点像做采访一样)

我们想要计算一个序列的相邻值的和,首先我们向前截断:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

然后我们向后截断:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

两者相交:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

最终聚合:


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这里有个可以计算累计求和的例子,我们这里引入一个给 transform 命名的能力来帮助你调试。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这个语言支持编译更加复杂的 transforms。他同时通过跟踪每一个运算操作计算层。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这里有个 2 层 transform 的例子,第一个对应于计算长度,第二个对应于累积总和。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

用 transformers 进行编程

使用这个函数库,我们可以编写完成一个复杂任务,Gail Weiss 给过我一个极其挑战的问题来打破这个步骤:我们可以加载一个添加任意长度数字的 Transformer 吗?

例如: 给一个字符串 “19492+23919”, 我们可以加载正确的输出吗?

如果你想自己尝试,我们提供了一个 版本 你可以自己试试。

挑战一:选择一个给定的索引

加载一个在索引 处全素都有值的序列


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

挑战二:转换

通过 位置将所有 token 移动到右侧。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

挑战三:最小化

计算序列的最小值。(这一步开始变得困难,我们版本用了 2 层注意力机制)


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

挑战四:第一索引

计算有 token q 的第一索引 (2 层)


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

挑战五:右对齐

右对齐一个填充序列。例:”” (2 层)


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

挑战六:分离

把一个序列在 token “v” 处分离成两部分然后右对齐 (2 层):


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

挑战七:滑动

将特殊 token “<” 替换为最接近的 “<” value (2 层):


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

挑战八:增加

你要执行两个数字的添加。这是步骤。


  1. 分成两部分。转制成整形。加入

“683+345” => [0, 0, 0, 9, 12, 8]

  1. 计算携带条款。三种可能性:1 个携带,0 不携带,< 也许有携带。

[0, 0, 0, 9, 12, 8] => “00<100”

  1. 滑动进位系数

“00<100” => 001100″

  1. 完成加法

这些都是 1 行代码。完整的系统是 6 个注意力机制。(尽管 Gail 说,如果你足够细心则可以在 5 个中完成!)。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



完美搞定!

参考资料 & 文内链接:

  • 如果你对这个主题感兴趣想了解更多,请查看论文:Thinking Like Transformers
  • 以及了解更多 RASP 语言
  • 如果你对「形式语言和神经网络」(FLaNN) 感兴趣或者有认识感兴趣的人,欢迎邀请他们加入我们的 线上社区!
  • 本篇博文,包含库、Notebook 和博文的内容
  • 本博客文章由 Sasha Rush 和 Gail Weiss 共同编写

<hr>

英文原文:Thinking Like Transformers

译者:innovation64 (李洋)

京东科技 姚永健

一、术语表:

1.对称算法

加密解密密钥是相同的。这些算法也叫秘密密钥算法或单密钥算法,它要求发送者和接收者在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都能对消息进行加密解密。只要通信需要保密,密钥就必须保密。

对称算法可分为两类。一次只对明文中的单个位(有时对字节)运算的算法称为序列算法或序列密码。另一类算法是对明文的一组位进行运算,这些位组称为分组,相应的算法称为分组算法或分组密码。现代计算机密码算法的典型分组长度为64位――这个长度大到足以防止分析破译,但又小到足以方便作用。



2.非对称算法

非对称算法也叫公开密钥加密,它是用两个数学相关的密钥对信息进行编码。在此系统中,其中一个密钥叫公开密钥,可随意发给期望与密钥持有者进行安全通信的人。公开密钥用于对信息加密。第二个密钥是私有密钥,属于密钥持有者,此人要仔细保存私有密钥。密钥持有者用私有密钥对收到的信息进行解密。

一般来说,都是公钥加密,私钥解密。如果系统双方需要相互通讯,可以生成两对密钥对。各自保存好自己的私钥和对方的公钥,用公钥加密,私钥进行解密



3.可逆加密算法

一般来说,涉及到秘钥之类的算法,都是可逆的。意思就是通过算法和秘钥加密之后,可以再次通过解密算法还原。常见的有DES、3DES、AES128、AES192、AES256 。其中AES后面的数字代表的是密钥长度。对称加密算法的安全性相对较低,比较适用的场景就是内网环境中的加解密。



4.不可逆算法

常见的不可逆加密算法有MD5,HMAC,SHA1、SHA-224、SHA-256、SHA-384,和SHA-512,其中SHA-224、SHA-256、SHA-384,和SHA-512我们可以统称为SHA2加密算法,SHA加密算法的安全性要比MD5更高,而SHA2加密算法比SHA1的要高。其中SHA后面的数字表示的是加密后的字符串长度,SHA1默认会产生一个160位的信息摘要。

不可逆加密算法最大的特点就是不需要密钥



5.加密盐

加密盐也是比较常听到的一个概念,盐就是一个随机字符串用来和我们的加密串拼接后进行加密。加盐主要是为了保证加密字符串的安全性。假如有一个加盐后的加密串,黑客通过一定手段得到这个加密串,他解密后拿到的明文,并不是我们加密前的字符串,而是加密前的字符串和盐组合的字符串,这样相对来说又增加了字符串的安全性

或者也可以用在签名,例如签名是对明文或者密文加盐后的签名,有人想串改数据,如果不知道这个盐和规则,那么接收方验签就会不通过,从而保证通讯的安全。

二、传统加密算法介绍

DES(Data Encryption Standard):

对称算法,数据加密标准,速度较快,适用于加密大量数据的场合。

AES算法:

是DES的升级版,属于对称算法。可逆

代码:AESUtil


RSA算法:

公钥加密算法,非对称,可逆

代码:RSAUtil


 

MD5算法:

信息摘要(Hash安全散列)算法,也叫哈希算法,哈希值也叫散列值,不可逆,不需要秘钥。

代码: MD5Util


SHA-256算法:

sha256算法也是一种密码散列函数,对于任意长度的消息,SHA256都会产生一个256bit长的散列值(哈希值),用于确保信息传输完整一致,称作消息摘要。这个摘要相当于是个长度为32个字节的数组,通常用一个长度为64的十六进制字符串来表示。

和MD5算法对比

相同点:

1、都是密码散列函数,加密不可逆。

2、都可以实现对任意长度对象加密,都不能防止碰撞。

安全性方面:

1、SHA256(称SHA2)的安全性最高,但是耗时要其他两种多很多。

2、md5相对来说比较容易碰撞,安全性没这么高。

性能方面:

以个60M的件为测试样本,经过1000次的测试平均值,这两种算法的表现如下:

MD5算法运1000次的平均时间为:226ms

SHA256算法运1000次的平均时间为:473ms

总而言之,md5和sha256都是密码散列函数,加密不可逆。虽然都不能防止碰撞,但是相对而言,md5比较容易碰撞,安全性没有sha256高。

代码:SHA256Util


三、国密算法介绍

简介:

为保障国家密码应用安全,2011年GJMM管理局发布《关于做好公钥密码算法升级工作的通知》,

要求自2011年3月1日起在建和拟建公钥密码基础设施电子认证系统和密钥管理系统应使用国密算法。

《金融和重要领域密码应用与创新发展工作规划(2018-2022年) 》以及相关法规文件也要求我国金融

和重要领域密码应用采用SM2国产密码算法体系。

国密算法是指GJMM管理局认定的一系列国产密码算法,包括SM1-SM9以及ZUC等。

其中SM1、SM4、SM5、SM6、SM7、SM8、ZUC等属于对称密码,SM2、SM9等属于公钥密码,SM3属于单向散列函数。

目前我国主要使用公开的SM2、SM3、SM4作为商用密码。



SM1:

SM1也叫商密1号算法,是一种国产的对称算法,分组长度和密钥长度都为 128 比特,该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。算法安全保密强度及相关软硬件实现性能与 AES 相当

SM2:

SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换RSA算法。

随着密码技术和计算机技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。

代码:SM2Util


SM3:

国产哈希算法,也叫消息摘要算法,可以用MD5作为对比理解。该算法已公开。校验结果为256位。SM3是中华人民共和国政府采用的一种密码散列函数标准,由GJMM管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。

在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法公开。据GJMM管理局表示,其安全性及效率与SHA-256相当。

代码:SM3Util


SM4:

无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。对标AES

代码:SM4Util


四、各类支付系统常见加密方式组合介绍

在支付系统交互中,有多种多样的加密方式组合,这里就简单介绍两钟常用的。

1.传统方式

用可逆,非对称算法(rsa,sm2等)使用对方公钥对报文内的关键信息进行加密得到的密文进行编码,然后再对密文编码后的串加盐后使用不可逆算法(sha256,md5,sm3等)进行签名,使用这些算法签名后得到的是一个16进制的串,签名放到另一个字段,一般是和加密后的信息并列的。

步骤:

1.使用对方的RSA公钥对明文进行加密,得到的密文进行base64编码,作为data

2.将data的值加上约定好的盐,使用sha256算法进行签名,得到的签名是16进制的串,放到sign

加密后的json:


接收后,先拿到密文,加入约定好的盐进行验签,验签通过后再用私钥进行解密。返回报文同理,只不过返回报文用的也是对方的公钥加密,对方接收后用自己的私钥解密。

demo:RSASha256Test


2. 一次一密+签名身份验证

生成一个对称算法秘钥,使用该秘钥对明文进行加密,然后将该秘钥使用对方的公钥进行加密,加密后编码,然后再对明文使用自己的私钥进行签名,因为私钥只有自己有,所以用自己的私钥签名后,对方使用你提供的公钥进行验签,就可以验证你的身份。

步骤:

1. 随机生成一个SM4密钥;

2. 使用SM4密钥加密密文,得到的密文进行base64编码,作为textToDecrypt

3. SM4密钥进行base64编码后,再使用对方的SM2公钥对这个base64串进行加密,得到的密文进行base64编码,作为keyCiphertext

4. 对第二步的明文使用第三方sm2私钥签名,得到的签名进行base64编码后作为signature

加密后json:


对方接收后,按照以上步骤再进行验签,解密等操作。

demo:GMSMTest


国密依赖pom




file

什么是ChatGPT?

ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列任务,因此有望成为提高办公、学习效率的工具。以前的人工智能AlphaGo打败了柯洁,但只是在围棋领域,而ChatGPT则已经进入了日常工作领域和生活世界。

不少和ChatGPT“聊过天”的网友纷纷感叹,“只有你想不到,没有ChatGPT办不成的”。上线仅仅2个月,ChatGPT的活跃用户就突破一亿。

什么是GreatSQL社区?

GreatSQL 社区成立于 2021 年,是一个 MySQL 开源数据库社区,由 万里数据库发起,致力于通过开放的社区合作,构建国内自主 MySQL 版本及开源数据库技术,推动中国开源数据库及应用生态繁荣发展。

我们社区的愿景是成为中国广受欢迎的开源数据库社区

什么是GreatSQL?

GreatSQL 开源数据库是适用于金融级应用的国内自主 MySQL 版本,专注于提升 MGR 可靠性及性能,支持 InnoDB 并行查询等特性,可以作为 MySQL 或 Percona Server 的可选替换,用于线上生产环境,且完全免费并兼容 MySQL 或 Percona Server。

GreatSQL 除了提升 MGR 性能及可靠性,还引入 InnoDB 事务锁优化及并行查询优化等特性,以及众多 BUG 修复。

ChatGPT对GreatSQL及社区的看法

既然这个ChatGPT能回答人类的问题,也可以完成人类提供的一系列任务,那么我想问问ChatGPT看看对我们GreatSQL有什么看法?以及对我们GreatSQL社区的建议等。

于是我带着这几个问题去询问了一下ChatGPT:

注:所有回答均为ChatGPT智能生成,无人工干预操作。

Q:ChatGPT您好,最近您在互联网可谓是爆火,我们GreatSQL社区想对您做一个采访不知道可以吗?

A:当然可以!我很高兴能够接受采访。GreatSQL社区那里有什么具体问题您想询问我?我会尽力回答您的每一个问题。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Q:您有听说过GreatSQL开源数据库以及GreatSQL开源社区吗?

A:作为一个人工智能语言模型,我并不具备听说功能。但是我可以了解到,GreatSQL是一款开源的关系型数据库管理系统,GreatSQL社区是围绕着GreatSQL建立起来的一个社区,为用户提供帮助、支持和交流的地方。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Q:那您在GreatSQL社区有注册账号吗?

A:很抱歉,作为一个人工智能模型,我没有注册账号的能力。我是通过API接口与外界进行交互的。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

没有注册的同学赶紧注册了! 地址:https://greatsql.cn/


Q:您知道MGR即MySQL组复制吗?

A:是的,我知道MySQL Group Replication(MGR)。它是MySQL数据库的一个分布式复制方案,旨在提供高可用性和数据冗余。通过MGR,MySQL数据库中的数据可以在多个服务器之间同步,以确保数据的完整性和可用性。因此,如果其中一台服务器故障,另一台服务器可以立即接管,并继续提供服务。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Q:您知道GreatSQL对MGR有哪些提升以及新特性吗?

A:对不起,由于我是一个通用人工智能模型,我并不知道GreatSQL对MySQL Group Replication(MGR)所做的具体提升和新特性。建议您可以直接询问GreatSQL社区,他们可以提供更详细和准确的回答。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

ChatGPT回答不上来,那让我来回答GreatSQL MGR的新特性有: 1.新增仲裁节点(投票节点)角色 2.新增快速单主模式 3.新增MGR网络开销阈值 4.自定义选主模式 以及稳定性提升bug修复和一些其他调整 详情可见:Changes in GreatSQL 8.0.25 (2021-8-18)


Q:您知道GreatSQL对MySQL做的其它提升有哪些吗?

A:很抱歉,我并不知道GreatSQL对MySQL所做的具体提升。因为GreatSQL是一个社区,它们的提升和新特性可能不断变化,我可能不能及时获得最新信息。建议您可以直接联系GreatSQL社区,他们可以提供更详细和准确的回答。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

ChatGPT还是回答不上来,相较于MySQL/Percona Server,GreatSQL主要增加几个特性: 地理标签&仲裁节点&快速单主&智能选主&并行查询 详情可见:19. GreatSQL特性 | 深入浅出MGR


Q:如果让您选用国产开源数据库您会选择GreatSQL吗?

A:作为一个人工智能程序,我不能选择或推荐任何数据库。选择数据库通常取决于项目的特殊要求,例如性能、可用性、成本等。建议您评估您的需求,并对多种数据库进行评估,以确定最合适的选择。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Q:如果有一个金融级别的场景,例如银行这样需要选择一款数据库,你选择以下哪款数据库呢?MySQL、Percona Server、GreatSQL

A:对于金融级别的场景,选择数据库需要考虑多方面因素,这包括但不限于安全性、可靠性、性能、可扩展性等。具体而言,最终的选择将取决于具体的业务需求和系统架构。

MySQL是一款广受欢迎的开源关系型数据库,已经被许多公司广泛使用。Percona Server是一款对MySQL进行的高性能扩展,它增加了一些性能优化特性。如果您没有特别的要求,MySQL或Percona Server都可以作为金融级别场景的数据库选项。

不过,我不清楚GreatSQL是否是适合金融级别场景的数据库,需要进一步评估其安全性、可靠性、性能和其他相关特性。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

GreatSQL开源数据库是适用于金融级应用的国内自主MySQL版本,感兴趣的同学可以来体验试用一下~ 3306π上海站 | 叶金荣《面向金融级 MGR 应用场景优化》


Q:您对GreatSQL和GreatSQL社区的未来发展有什么建议吗?例如如何提高知名度,提升客户满意度等

A:对于GreatSQL和GreatSQL社区的未来发展,以下是一些可能的建议:

加强技术:不断提高产品质量和功能,满足客户需求,保持与竞争对手的技术差距。

专注客户需求:积极聆听客户反馈,提高客户满意度。

提高知名度:通过技术演讲、博客、社交媒体等途径提高GreatSQL和GreatSQL社区的知名度。

加强合作:与相关技术和社区建立合作关系,提高GreatSQL和GreatSQL社区的知名度和影响力。

加强市场推广:通过市场推广活动,提高GreatSQL和GreatSQL社区的知名度。

人才培养:投入人才培养,确保GreatSQL和GreatSQL社区有足够的人力支持。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Q:您对GreatSQL和GreatSQL社区有什么看法和建议吗?

A:作为一个人工智能程序,我没有足够的信息来对GreatSQL和GreatSQL社区做出看法和建议。我的目的是提供客观、无偏的信息,并且无法参与评判或选择。如果您对GreatSQL和GreatSQL社区有任何问题,建议您直接询问相关专家或与GreatSQL社区联系。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

社区未来发展和未来展望 GreatSQL特性介绍及前景展望 | 数据技术嘉年华2021分享PPT发布


Q:我们社区发布了很多关于数据库的技术文章,您可以写一篇关于数据库的技术文章吗?例如如何构建MGR集群

A:好的,我可以写一篇关于如何构建MySQL Group Replication (MGR) 集群的技术文章。

MySQL Group Replication (MGR) 是一种基于复制的高可用解决方案,它提供了自动故障转移和数据冗余的能力。MGR 集群通过在多个MySQL服务器间进行同步复制,来保证数据的完整性和高可用性。

构建 MGR 集群需要以下步骤:

安装和配置MySQL服务器:在每台服务器上安装并配置MySQL服务器。

启用Group Replication插件:在每台服务器上启用Group Replication插件。

配置Group Replication:配置Group Replication选项,以指定每台服务器的角色(例如主服务器或从服务器)和其他相关选项。

配置网络:配置防火墙规则和网络设置,以确保每台服务器可以通过网络与其他服务器通信。

加入集群:在每台服务器上运行命令,将其加入MGR集群。

测试:测试MGR集群是否正常工作,并确保数据同步正常进行。

以上是构建MGR集群的大致步骤,每个步骤都需要更详细的操作和

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

写到最后断掉了不过还是挺厉害的


Q:你的回答很笼统,很好奇你从哪里了解到这些资讯的?

A:作为一个人工智能程序,我是通过深度学习算法培训的。我的知识库是来自互联网和公开数据源,这些数据源包含了关于大量主题的信息,其中包括数据库和相关技术。但是,由于数据源可能不完整和不准确,因此我的回答可能不是最准确的。如果您对任何信息有疑问,建议您查询其他权威资源以确保准确性。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


Q:感谢您接受我的采访,欢迎您对GreatSQL和GreatSQL社区有更深入的了解~

A:不客气!如果您有任何其他问题,请随时联系我。我很高兴能够帮助您。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)


您的建议

了解完了ChatGPT对我们GreatSQL和社区的看法,我们想知道您对GreatSQL和社区的看法,麻烦您可以花几分钟时间填写下问卷

https://wj..com/s2//9e09

可以获得精美礼品以及我们的免费技术支持

作者:京东零售 周凯

一.前言

Rust 语言由 Mozilla 开发,最早发布于 2014 年 9 月,是一种高效、可靠的通用高级语言。其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言。Rust语言具备如下特性:

•高性能 – Rust 速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成。

•可靠性 – Rust 丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误。

•生产力 – Rust 拥有出色的文档、友好的编译器和清晰的错误提示信息, 还集成了一流的工具 —— 包管理器和构建工具, 智能地自动补全和类型检验的多编辑器支持, 以及自动格式化代码等等。

Rust最近几年发展非常迅速,广受一线程序员的欢迎,Rust有一个官方维护的模块库(crates.io: Rust Package Registry),可以通过编译器自带的cargo管理工具方便的引入模块,目前crates.io上面的模块数量已经突破10万个,仍在快速增长,此情此景仿佛过去10年node.js的发展情景再现。

12月11日,Linus Torvalds发布了Linux6.1内核稳定版,并带来一个重磅的新闻,即Linux6.1将包含对Rust语言的原生支持。尽管这一功能仍在构建中,不过这也意味着,在可见的将来,Linux的历史将翻开崭新的一页——除了C之外,开发人员将第一次能够使用另一种语言Rust进行内核开发。

在近几年的讨论中,是否在Linux内核中引入Rust多次成为议题。不过包括 Torvalds在内的一众关键人物均对此表示了期待。早在2019年,Alex Gaynor和Geoffrey Thomas就曾于Linux Security Summit安全峰会上进行了演讲。他们指出,在Android和Ubuntu中,约有三分之二的内核漏洞被分配到CVE中,这些漏洞都是来自于内存安全问题。原则上,Rust可以通过其type system和borrow checker所提供的更安全的API来完全避免这类错误。简言之,Rust比C更安全。谷歌Android团队的Wedson Almeida Filho也曾公开表示:“我们觉得Rust现在已经准备好加入C语言,作为实现内核的实用语言。它可以帮助我们减少特权代码中潜在错误和安全漏洞的数量,同时很好地与核心内核配合并保留其性能特征。”

当前,谷歌在Android中广泛使用Rust。在那里,“目标不是将现有的C/C++转换为Rust,而是随着时间的推移,将新代码的开发转移到内存安全语言”。这一言论也逐渐在实践中得到论证。“随着进入Android的新内存不安全代码的数量减少,内存安全漏洞的数量也在减少。从2019年到2022年,相关漏洞占比已从Android总漏洞的76%下降到35%。2022年,在Android漏洞排行中,内存安全漏洞第一次不再是主因。”

本文将探寻相比于其他语言,Rust是怎样实现内存安全的。Rust针对创建于内存堆上的复杂数据类型,设计了一套独有的内存管理机制,该套机制包含变量的所有权机制、变量的作用域、变量的引用与借用,并专门针对字符串、数组、组等复杂类型设计了slice类型,下面将具体讲述这些机制与规则。

二.变量的所有权

Rust 的核心功能(之一)是 所有权ownership)。虽然该功能很容易解释,但它对语言的其他部分有着深刻的影响。

所有程序都必须管理其运行时使用计算机内存的方式。一些语言中具有垃圾回收机制,在程序运行时有规律地寻找不再使用的内存;在另一些语言中,程序员必须亲自分配和释放内存。Rust 则选择了第三种方式:通过所有权系统管理内存,编译器在编译时会根据一系列的规则进行检查。如果违反了任何这些规则,程序都不能编译。在运行时,所有权系统的任何功能都不会减慢程序。

因为所有权对很多程序员来说都是一个新概念,需要一些时间来适应。好消息是随着你对 Rust 和所有权系统的规则越来越有经验,你就越能自然地编写出安全和高效的代码。持之以恒!

当你理解了所有权,你将有一个坚实的基础来理解那些使 Rust 独特的功能。在本章中,我们将通过完成一些示例来介绍所有权,这些示例基于一个常用的数据结构:字符串。

栈(Stack)与堆(Heap)在很多语言中,你并不需要经常考虑到栈与堆。不过在像 Rust 这样的系统编程语言中,值是位于栈上还是堆上在更大程度上影响了语言的行为以及为何必须做出这样的抉择。我们会在本文的稍后部分描述所有权与栈和堆相关的内容,所以这里只是一个用来预热的简要解释。栈和堆都是代码在运行时可供使用的内存,但是它们的结构不同。栈以放入值的顺序存储值并以相反顺序取出值。这也被称作 后进先出(last in, first out)。想象一下一叠盘子:当增加更多盘子时,把它们放在盘子堆的顶部,当需要盘子时,也从顶部拿走。不能从中间也不能从底部增加或拿走盘子!增加数据叫做 进栈(pushing onto the stack),而移出数据叫做 出栈(popping off the stack)。栈中的所有数据都必须占用已知且固定的大小。在编译时大小未知或大小可能变化的数据,要改为存储在堆上。 堆是缺乏组织的:当向堆放入数据时,你要请求一定大小的空间。内存分配器(memory allocator)在堆的某处找到一块足够大的空位,把它标记为已使用,并返回一个表示该位置地址的 指针(pointer)。这个过程称作 在堆上分配内存(allocating on the heap),有时简称为 “分配”(allocating)。(将数据推入栈中并不被认为是分配)。因为指向放入堆中数据的指针是已知的并且大小是固定的,你可以将该指针存储在栈上,不过当需要实际数据时,必须访问指针。想象一下去餐馆就座吃饭。当进入时,你说明有几个人,餐馆员工会找到一个够大的空桌子并领你们过去。如果有人来迟了,他们也可以通过询问来找到你们坐在哪。入栈比在堆上分配内存要快,因为(入栈时)分配器无需为存储新数据去搜索内存空间;其位置总是在栈顶。相比之下,在堆上分配内存则需要更多的工作,这是因为分配器必须首先找到一块足够存放数据的内存空间,并接着做一些记录为下一次分配做准备。访问堆上的数据比访问栈上的数据慢,因为必须通过指针来访问。现代处理器在内存中跳转越少就越快(缓存)。继续类比,假设有一个服务员在餐厅里处理多个桌子的点菜。在一个桌子报完所有菜后再移动到下一个桌子是最有效率的。从桌子 A 听一个菜,接着桌子 B 听一个菜,然后再桌子 A,然后再桌子 B 这样的流程会更加缓慢。出于同样原因,处理器在处理的数据彼此较近的时候(比如在栈上)比较远的时候(比如可能在堆上)能更好的工作。当你的代码调用一个函数时,传递给函数的值(包括可能指向堆上数据的指针)和函数的局部变量被压入栈中。当函数结束时,这些值被移出栈。跟踪哪部分代码正在使用堆上的哪些数据,最大限度的减少堆上的重复数据的数量,以及清理堆上不再使用的数据确保不会耗尽空间,这些问题正是所有权系统要处理的。一旦理解了所有权,你就不需要经常考虑栈和堆了,不过明白了所有权的主要目的就是为了管理堆数据,能够帮助解释为什么所有权要以这种方式工作。

2.1.所有权规则

首先,让我们看一下所有权的规则。当我们通过举例说明时,请谨记这些规则:

Rust 中的每一个值都有一个 所有者(owner)。值在任一时刻有且只有一个所有者。当所有者(变量)离开作用域,这个值将被丢弃。

2.2.变量作用域

既然我们已经掌握了基本语法,将不会在之后的例子中包含 代码,所以如果你是一路跟过来的,必须手动将之后例子的代码放入一个 函数中。这样,例子将显得更加简明,使我们可以关注实际细节而不是样板代码。

在所有权的第一个例子中,我们看看一些变量的 作用域scope)。作用域是一个项(item)在程序中有效的范围。假设有这样一个变量:


变量 绑定到了一个字符串字面值,这个字符串值是硬编码进程序代码中的。这个变量从声明的点开始直到当前 作用域 结束时都是有效的。示例 1 中的注释标明了变量 在何处是有效的。


示例 1:一个变量和其有效的作用域

换句话说,这里有两个重要的时间点:

•当 s 时,它就是有效的。

•这一直持续到它 离开作用域 为止

目前为止,变量是否有效与作用域的关系跟其他编程语言是类似的。现在我们在此基础上介绍 类型。

2.3.String 类型

为了演示所有权的规则,我们需要一个比基本数据类型都要复杂的数据类型。前面介绍的类型都是已知大小的,可以存储在栈中,并且当离开作用域时被移出栈,如果代码的另一部分需要在不同的作用域中使用相同的值,可以快速简单地复制它们来创建一个新的独立实例。不过我们需要寻找一个存储在堆上的数据来探索 Rust 是如何知道该在何时清理数据的。

我们会专注于 与所有权相关的部分。这些方面也同样适用于标准库提供的或你自己创建的其他复杂数据类型。

我们已经见过字符串字面值,即被硬编码进程序里的字符串值。字符串字面值是很方便的,不过它们并不适合使用文本的每一种场景。原因之一就是它们是不可变的。另一个原因是并非所有字符串的值都能在编写代码时就知道:例如,要是想获取用户输入并存储该怎么办呢?为此,Rust 有第二个字符串类型,。这个类型管理被分配到堆上的数据,所以能够存储在编译时未知大小的文本。可以使用 函数基于字符串字面值来创建 ,如下:


这两个冒号 是运算符,允许将特定的 函数置于 类型的命名空间(namespace)下,而不需要使用类似 这样的名字。

可以 修改此类字符串 :


那么这里有什么区别呢?为什么 可变而字面值却不行呢?区别在于两个类型对内存的处理上。

2.4.内存与分配

就字符串字面值来说,我们在编译时就知道其内容,所以文本被直接硬编码进最终的可执行文件中。这使得字符串字面值快速且高效。不过这些特性都只得益于字符串字面值的不可变性。不幸的是,我们不能为了每一个在编译时大小未知的文本而将一块内存放入二进制文件中,并且它的大小还可能随着程序运行而改变。

对于 类型,为了支持一个可变,可增长的文本片段,需要在堆上分配一块在编译时未知大小的内存来存放内容。这意味着:

•必须在运行时向内存分配器(memory allocator)请求内存。

第一部分由我们完成:当调用 时,它的实现 (implementation) 请求其所需的内存。这在编程语言中是非常通用的。

然而,第二部分实现起来就各有区别了。在有 垃圾回收garbage collectorGC)的语言中, GC 记录并清除不再使用的内存,而我们并不需要关心它。在大部分没有 GC 的语言中,识别出不再使用的内存并调用代码显式释放就是我们的责任了,跟请求内存的时候一样。从历史的角度上说正确处理内存回收曾经是一个困难的编程问题。如果忘记回收了会浪费内存。如果过早回收了,将会出现无效变量。如果重复回收,这也是个 bug。我们需要精确的为一个 配对一个 。

Rust 采取了一个不同的策略:内存在拥有它的变量离开作用域后就被自动释放。下面是示例 1 中作用域例子的一个使用 而不是字符串字面值的版本:


这是一个将 需要的内存返回给分配器的很自然的位置:当 离开作用域的时候。当变量离开作用域,Rust 为我们调用一个特殊的函数。这个函数叫做 ,在这里 的作者可以放置释放内存的代码。Rust 在结尾的 处自动调用 。

注意:在 C++ 中,这种 item 在生命周期结束时释放资源的模式有时被称作 资源获取即初始化(Resource Acquisition Is Initialization (RAII))。如果你使用过 RAII 模式的话应该对 Rust 的 drop 函数并不陌生。

这个模式对编写 Rust 代码的方式有着深远的影响。现在它看起来很简单,不过在更复杂的场景下代码的行为可能是不可预测的,比如当有多个变量使用在堆上分配的内存时。现在让我们探索一些这样的场景。

2.4.1.变量与数据交互的方式(一):移动

在Rust 中,多个变量可以采取不同的方式与同一数据进行交互。让我们看看示例 2 中一个使用整型的例子。


示例 2:将变量 x 的整数值赋给 y

我们大致可以猜到这在干什么:“将 绑定到 ;接着生成一个值 的拷贝并绑定到 ”。现在有了两个变量, 和 ,都等于 。这也正是事实上发生了的,因为整数是有已知固定大小的简单值,所以这两个 被放入了栈中。

现在看看这个 版本:


这看起来与上面的代码非常类似,所以我们可能会假设他们的运行方式也是类似的:也就是说,第二行可能会生成一个 的拷贝并绑定到 上。不过,事实上并不完全是这样。

看看图1 以了解 的底层会发生什么。 由三部分组成,如图左侧所示:一个指向存放字符串内容内存的指针,一个长度,和一个容量。这一组数据存储在栈上。右侧则是堆上存放内容的内存部分。

String in memory

图 1:将值 “hello” 绑定给 s1 的 String 在内存中的表现形式

长度表示 的内容当前使用了多少字节的内存。容量是 从分配器总共获取了多少字节的内存。长度与容量的区别是很重要的,不过在当前上下文中并不重要,所以现在可以忽略容量。

当我们将 赋值给 , 的数据被复制了,这意味着我们从栈上拷贝了它的指针、长度和容量。我们并没有复制指针指向的堆上数据。换句话说,内存中数据的表现如图2 所示。

s1 and s2 pointing to the same value

图 2:变量 s2 的内存表现,它有一份 s1 指针、长度和容量的拷贝

这个表现形式看起来 并不像 图3 中的那样,如果 Rust 也拷贝了堆上的数据,那么内存看起来就是这样的。如果 Rust 这么做了,那么操作 在堆上数据比较大的时候会对运行时性能造成非常大的影响。

s1 and s2 to two places

图 3:另一个 s2 = s1 时可能的内存表现,如果 Rust 同时也拷贝了堆上的数据的话

之前我们提到过当变量离开作用域后,Rust 自动调用 函数并清理变量的堆内存。不过图 2 展示了两个数据指针指向了同一位置。这就有了一个问题:当 和 离开作用域,他们都会尝试释放相同的内存。这是一个叫做 二次释放double free)的错误,也是之前提到过的内存安全性 bug 之一。两次释放(相同)内存会导致内存污染,它可能会导致潜在的安全漏洞。

为了确保内存安全,在 之后,Rust 认为 不再有效,因此 Rust 不需要在 离开作用域后清理任何东西。看看在 被创建之后尝试使用 会发生什么;这段代码不能运行:


你会得到一个类似如下的错误,因为 Rust 禁止你使用无效的引用。


如果你在其他语言中听说过术语 浅拷贝shallow copy)和 深拷贝deep copy),那么拷贝指针、长度和容量而不拷贝数据可能听起来像浅拷贝。不过因为 Rust 同时使第一个变量无效了,这个操作被称为 移动move),而不是浅拷贝。上面的例子可以解读为 被 移动 到了 中。那么具体发生了什么,如图 4 所示。

s1 moved to s2

图 4:s1 无效之后的内存表现

这样就解决了我们的问题!因为只有 是有效的,当其离开作用域,它就释放自己的内存,完毕。

另外,这里还隐含了一个设计选择:Rust 永远也不会自动创建数据的 “深拷贝”。因此,任何 自动 的复制可以被认为对运行时性能影响较小。

2.4.2.变量与数据交互的方式(二):克隆

如果我们 确实 需要深度复制 中堆上的数据,而不仅仅是栈上的数据,可以使用一个叫做 的通用函数。第五章会讨论方法语法,不过因为方法在很多语言中是一个常见功能,所以之前你可能已经见过了。

这是一个实际使用 方法的例子:


这段代码能正常运行,并且明确产生图 3 中行为,这里堆上的数据 确实 被复制了。

当出现 调用时,你知道一些特定的代码被执行而且这些代码可能相当消耗资源。你很容易察觉到一些不寻常的事情正在发生。

2.4.3.只在栈上的数据:拷贝

这里还有一个没有提到的小窍门。这些代码使用了整型并且是有效的,他们是示例 2 中的一部分:


但这段代码似乎与我们刚刚学到的内容相矛盾:没有调用 ,不过 依然有效且没有被移动到 中。

原因是像整型这样的在编译时已知大小的类型被整个存储在栈上,所以拷贝其实际的值是快速的。这意味着没有理由在创建变量 后使 无效。换句话说,这里没有深浅拷贝的区别,所以这里调用 并不会与通常的浅拷贝有什么不同,我们可以不用管它。

Rust 有一个叫做 trait 的特殊注解,可以用在类似整型这样的存储在栈上的类型上。如果一个类型实现了 trait,那么一个旧的变量在将其赋值给其他变量后仍然可用。

Rust 不允许自身或其任何部分实现了 trait 的类型使用 trait。如果我们对其值离开作用域时需要特殊处理的类型使用 注解,将会出现一个编译时错误。

那么哪些类型实现了 trait 呢?你可以查看给定类型的文档来确认,不过作为一个通用的规则,任何一组简单标量值的组合都可以实现 ,任何不需要分配内存或某种形式资源的类型都可以实现 。如下是一些 的类型:

•所有整数类型,比如 u32。

•布尔类型,bool,它的值是 true 和 false。

•所有浮点数类型,比如 f64。

•字符类型,char。

•组,当且仅当其包含的类型也都实现 Copy 的时候。比如,(i32, i32) 实现了 Copy,但 (i32, String) 就没有。

2.5.所有权与函数

将值传递给函数与给变量赋值的原理相似。向函数传递值可能会移动或者复制,就像赋值语句一样。示例 3 使用注释展示变量何时进入和离开作用域:

文件名: src/main.rs


示例 3:带有所有权和作用域注释的函数

当尝试在调用 后使用 时,Rust 会抛出一个编译时错误。这些静态检查使我们免于犯错。试试在 函数中添加使用 和 的代码来看看哪里能使用他们,以及所有权规则会在哪里阻止我们这么做。

2.6.返回值与作用域

返回值也可以转移所有权。示例 4 展示了一个返回了某些值的示例,与示例 3 一样带有类似的注释。

文件名: src/main.rs


示例 4: 转移返回值的所有权

变量的所有权总是遵循相同的模式:将值赋给另一个变量时移动它。当持有堆中数据值的变量离开作用域时,其值将通过 被清理掉,除非数据被移动为另一个变量所有。

虽然这样是可以的,但是在每一个函数中都获取所有权并接着返回所有权有些啰嗦。如果我们想要函数使用一个值但不获取所有权该怎么办呢?如果我们还要接着使用它的话,每次都传进去再返回来就有点烦人了,除此之外,我们也可能想返回函数体中产生的一些数据。

我们可以使用组来返回多个值,如示例 5 所示。

文件名: src/main.rs


示例 5: 返回参数的所有权

但是这未免有些形式主义,而且这种场景应该很常见。幸运的是,Rust 对此提供了一个不用获取所有权就可以使用值的功能,叫做 引用references)。

三.引用与借用

示例 5 中的组代码有这样一个问题:我们必须将 返回给调用函数,以便在调用 后仍能使用 ,因为 被移动到了 内。相反我们可以提供一个 值的引用(reference)。引用reference)像一个指针,因为它是一个地址,我们可以由此访问储存于该地址的属于其他变量的数据。 与指针不同,引用确保指向某个特定类型的有效值。

下面是如何定义并使用一个(新的) 函数,它以一个对象的引用作为参数而不是获取值的所有权:

文件名: src/main.rs


首先,注意变量声明和函数返回值中的所有组代码都消失了。其次,注意我们传递 给 ,同时在函数定义中,我们获取 而不是 。这些 & 符号就是 引用,它们允许你使用值但不获取其所有权。图 5 展示了一张示意图。

&String s pointing at String s1

图 5:&String s 指向 String s1 示意图

注意:与使用 & 引用相反的操作是 解引用(dereferencing),它使用解引用运算符,*。我们将会在第八章遇到一些解引用运算符,并在第十五章详细讨论解引用。

仔细看看这个函数调用:


语法让我们创建一个 指向 值 的引用,但是并不拥有它。因为并不拥有这个值,所以当引用停止使用时,它所指向的值也不会被丢弃。

同理,函数签名使用 来表明参数 的类型是一个引用。让我们增加一些解释性的注释:


变量 有效的作用域与函数参数的作用域一样,不过当 停止使用时并不丢弃引用指向的数据,因为 并没有所有权。当函数使用引用而不是实际值作为参数,无需返回值来交还所有权,因为就不曾拥有所有权。

我们将创建一个引用的行为称为 借用borrowing)。正如现实生活中,如果一个人拥有某样东西,你可以从他那里借来。当你使用完毕,必须还回去。我们并不拥有它。

如果我们尝试修改借用的变量呢?尝试示例 6 中的代码。剧透:这行不通!

文件名: src/main.rs


示例 6:尝试修改借用的值

这里是错误:


正如变量默认是不可变的,引用也一样。(默认)不允许修改引用的值。

3.1.可变引用

我们通过一个小调整就能修复示例 6 代码中的错误,允许我们修改一个借用的值,这就是 可变引用mutable reference):

文件名: src/main.rs


首先,我们必须将 改为 。然后在调用 函数的地方创建一个可变引用 ,并更新函数签名以接受一个可变引用 。这就非常清楚地表明, 函数将改变它所借用的值。

可变引用有一个很大的限制:如果你有一个对该变量的可变引用,你就不能再创建对该变量的引用。这些尝试创建两个 的可变引用的代码会失败:

文件名: src/main.rs


错误如下:


这个报错说这段代码是无效的,因为我们不能在同一时间多次将 作为可变变量借用。第一个可变的借入在 中,并且必须持续到在 中使用它,但是在那个可变引用的创建和它的使用之间,我们又尝试在 中创建另一个可变引用,该引用借用与 相同的数据。

这一限制以一种非常小心谨慎的方式允许可变性,防止同一时间对同一数据存在多个可变引用。新 Rustacean 们经常难以适应这一点,因为大部分语言中变量任何时候都是可变的。这个限制的好处是 Rust 可以在编译时就避免数据竞争。数据竞争data race)类似于竞态条件,它可由这三个行为造成:

•两个或更多指针同时访问同一数据。

•至少有一个指针被用来写入数据。

•没有同步数据访问的机制。

数据竞争会导致未定义行为,难以在运行时追踪,并且难以诊断和修复;Rust 避免了这种情况的发生,因为它甚至不会编译存在数据竞争的代码!

一如既往,可以使用大括号来创建一个新的作用域,以允许拥有多个可变引用,只是不能 同时 拥有:


Rust 在同时使用可变与不可变引用时也采用的类似的规则。这些代码会导致一个错误:


错误如下:


错误提示我们也不能在拥有不可变引用的同时拥有可变引用。

不可变引用的用户可不希望在他们的眼皮底下值就被意外的改变了!然而,多个不可变引用是可以的,因为没有哪个只能读取数据的人有能力影响其他人读取到的数据。

注意一个引用的作用域从声明的地方开始一直持续到最后一次使用为止。例如,因为最后一次使用不可变引用(),发生在声明可变引用之前,所以如下代码是可以编译的:


不可变引用 和 的作用域在 最后一次使用之后结束,这也是创建可变引用 的地方。它们的作用域没有重叠,所以代码是可以编译的。编译器在作用域结束之前判断不再使用的引用的能力被称为 非词法作用域生命周期Non-Lexical Lifetimes,简称 NLL)。

尽管这些错误有时使人沮丧,但请牢记这是 Rust 编译器在提前指出一个潜在的 bug(在编译时而不是在运行时)并精准显示问题所在。这样你就不必去跟踪为何数据并不是你想象中的那样。

3.2.悬垂引用(Dangling References)

在具有指针的语言中,很容易通过释放内存时保留指向它的指针而错误地生成一个 悬垂指针dangling pointer),所谓悬垂指针是其指向的内存可能已经被分配给其它持有者。相比之下,在 Rust 中编译器确保引用永远也不会变成悬垂状态:当你拥有一些数据的引用,编译器确保数据不会在其引用之前离开作用域。

让我们尝试创建一个悬垂引用,Rust 会通过一个编译时错误来避免:

文件名: src/main.rs


这里是错误:


错误信息引用了一个我们还未介绍的功能:生命周期(lifetimes)。第十章会详细介绍生命周期。不过,如果你不理会生命周期部分,错误信息中确实包含了为什么这段代码有问题的关键信息:


让我们仔细看看我们的 代码的每一步到底发生了什么:

文件名: src/main.rs


因为 是在 函数内创建的,当 的代码执行完毕后, 将被释放。不过我们尝试返回它的引用。这意味着这个引用会指向一个无效的 ,这可不对!Rust 不会允许我们这么做。

这里的解决方法是直接返回 :


这样就没有任何错误了。所有权被移动出去,所以没有值被释放。

3.3.引用的规则

让我们概括一下之前对引用的讨论:

在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。

•引用必须总是有效的。

接下来,我们来看看另一种不同类型的引用:slice。

四.Slice 类型

slice 允许你引用集合中一段连续的素序列,而不用引用整个集合。slice 是一类引用,所以它没有所有权。

这里有一个编程小习题:编写一个函数,该函数接收一个用空格分隔单词的字符串,并返回在该字符串中找到的第一个单词。如果函数在该字符串中并未找到空格,则整个字符串就是一个单词,所以应该返回整个字符串。

让我们推敲下如何不用 slice 编写这个函数的签名,来理解 slice 能解决的问题:


函数有一个参数 。因为我们不需要所有权,所以这没有问题。不过应该返回什么呢?我们并没有一个真正获取 部分 字符串的办法。不过,我们可以返回单词结尾的索引,结尾由一个空格表示。试试如示例 7 中的代码。

文件名: src/main.rs


示例 7:first_word 函数返回 String 参数的一个字节索引值

因为需要逐个素的检查 中的值是否为空格,需要用 方法将 转化为字节数组:


接下来,使用 方法在字节数组上创建一个迭代器:


上述代码中, 方法返回集合中的每一个素,而 包装了 的结果,将这些素作为组的一部分来返回。 返回的组中,第一个素是索引,第二个素是集合中素的引用。这比我们自己计算索引要方便一些。

因为 方法返回一个组,我们可以使用模式来解构,我们将在第六章中进一步讨论有关模式的问题。所以在 循环中,我们指定了一个模式,其中组中的 是索引而组中的 是单个字节。因为我们从 中获取了集合素的引用,所以模式中使用了 。

在 循环中,我们通过字节的字面值语法来寻找代表空格的字节。如果找到了一个空格,返回它的位置。否则,使用 返回字符串的长度:


现在有了一个找到字符串中第一个单词结尾索引的方法,不过这有一个问题。我们返回了一个独立的 ,不过它只在 的上下文中才是一个有意义的数字。换句话说,因为它是一个与 相分离的值,无法保证将来它仍然有效。考虑一下示例 8 中使用了示例 7 中 函数的程序。

文件名: src/main.rs


示例 8:存储 first_word 函数调用的返回值并接着改变 String 的内容

这个程序编译时没有任何错误,而且在调用 之后使用 也不会出错。因为 与 状态完全没有联系,所以 仍然包含值 。可以尝试用值 来提取变量 的第一个单词,不过这是有 bug 的,因为在我们将 保存到 之后 的内容已经改变。

我们不得不时刻担心 的索引与 中的数据不再同步,这很啰嗦且易出错!如果编写这么一个 函数的话,管理索引这件事将更加容易出问题。它的签名看起来像这样:


现在我们要跟踪一个开始索引 一个结尾索引,同时有了更多从数据的某个特定状态计算而来的值,但都完全没有与这个状态相关联。现在有三个飘忽不定的不相关变量需要保持同步。

幸运的是,Rust 为这个问题提供了一个解决方法:字符串 slice。

4.1.字符串 slice

字符串 slicestring slice)是 中一部分值的引用,它看起来像这样:


不同于整个 的引用, 是一个部分 的引用,由一个额外的 部分指定。可以使用一个由中括号中的 指定的 range 创建一个 slice,其中 是 slice 的第一个位置, 则是 slice 最后一个位置的后一个值。在其内部,slice 的数据结构存储了 slice 的开始位置和长度,长度对应于 减去 的值。所以对于 的情况, 将是一个包含指向 索引 6 的指针和长度值 5 的 slice。

图 6 展示了一个图例。

world containing a pointer to the byte at index 6 of String s and a length 5

图 6:引用了部分 String 的字符串 slice

对于 Rust 的 range 语法,如果想要从索引 0 开始,可以不写两个点号之前的值。换句话说,如下两个语句是相同的:


依此类推,如果 slice 包含 的最后一个字节,也可以舍弃尾部的数字。这意味着如下也是相同的:


也可以同时舍弃这两个值来获取整个字符串的 slice。所以如下亦是相同的:


注意:字符串 slice range 的索引必须位于有效的 UTF-8 字符边界内,如果尝试从一个多字节字符的中间位置创建字符串 slice,则程序将会因错误而退出。出于介绍字符串 slice 的目的,本部分假设只使用 ASCII 字符集;第八章的 “使用字符串存储 UTF-8 编码的文本” 部分会更加全面的讨论 UTF-8 处理问题。

在记住所有这些知识后,让我们重写 来返回一个 slice。“字符串 slice” 的类型声明写作 :

文件名: src/main.rs


我们使用跟示例 7 相同的方式获取单词结尾的索引,通过寻找第一个出现的空格。当找到一个空格,我们返回一个字符串 slice,它使用字符串的开始和空格的索引作为开始和结束的索引。

现在当调用 时,会返回与底层数据关联的单个值。这个值由一个 slice 开始位置的引用和 slice 中素的数量组成。

函数也可以改为返回一个 slice:


现在我们有了一个不易混淆且直观的 API 了,因为编译器会确保指向 的引用持续有效。还记得示例 8 程序中,那个当我们获取第一个单词结尾的索引后,接着就清除了字符串导致索引就无效的 bug 吗?那些代码在逻辑上是不正确的,但却没有显示任何直接的错误。问题会在之后尝试对空字符串使用第一个单词的索引时出现。slice 就不可能出现这种 bug 并让我们更早的知道出问题了。使用 slice 版本的 会抛出一个编译时错误:

文件名: src/main.rs


这里是编译错误:


回忆一下借用规则,当拥有某值的不可变引用时,就不能再获取一个可变引用。因为 需要清空 ,它尝试获取一个可变引用。在调用 之后的 使用了 中的引用,所以这个不可变的引用在此时必须仍然有效。Rust 不允许 中的可变引用和 中的不可变引用同时存在,因此编译失败。Rust 不仅使得我们的 API 简单易用,也在编译时就消除了一整类的错误!

4.1.1.字符串字面值就是 slice

还记得我们讲到过字符串字面值被储存在二进制文件中吗?现在知道 slice 了,我们就可以正确地理解字符串字面值了:


这里 的类型是 :它是一个指向二进制程序特定位置的 slice。这也就是为什么字符串字面值是不可变的; 是一个不可变引用。

4.1.2.字符串 slice 作为参数

在知道了能够获取字面值和 的 slice 后,我们对 做了改进,这是它的签名:


而更有经验的 Rustacean 会编写出示例 9 中的签名,因为它使得可以对 值和 值使用相同的函数:


示例 9: 通过将 s 参数的类型改为字符串 slice 来改进 first_word 函数

如果有一个字符串 slice,可以直接传递它。如果有一个 ,则可以传递整个 的 slice 或对 的引用。定义一个获取字符串 slice 而不是 引用的函数使得我们的 API 更加通用并且不会丢失任何功能:

文件名: src/main.rs


4.2.其他类型的 slice

字符串 slice,正如你想象的那样,是针对字符串的。不过也有更通用的 slice 类型。考虑一下这个数组:


就跟我们想要获取字符串的一部分那样,我们也会想要引用数组的一部分。我们可以这样做:


这个 slice 的类型是 。它跟字符串 slice 的工作方式一样,通过存储第一个集合素的引用和一个集合总长度。你可以对其他所有集合使用这类 slice。第八章讲到 vector 时会详细讨论这些集合。

五.总结

所有权、借用和 slice 这些概念让 Rust 程序在编译时确保内存安全。Rust 语言提供了跟其他系统编程语言相同的方式来控制你使用的内存,但拥有数据所有者在离开作用域后自动清除其数据的功能意味着你无须额外编写和调试相关的控制代码。Rust自带的这些机制虽然牺牲了一些灵活性,但也从根本上保证了内存的安全,只要遵循这些规则,就能轻松写出安全的代码。

六.引用

[1] Rust 教程 | 菜鸟教程 (runoob.com)

[2] 除了RUST,还有国产架构:Linux6.1内核稳定版首发布!_中文科技资讯 提供快捷产业新资讯 创新驱动商业 (citnews.com.cn)

[3] crates.io: Rust Package Registry

[4] 字节跳动在 Rust 微服务方向的探索和实践 | QCon_代码_问题_时候 (sohu.com)

[5] Rust 程序设计语言 – Rust 程序设计语言 简体中文版 (kaisery.github.io)

架构

基于MASA的云原生技术架构

图片

我们基于MASA去做了一个云原生技术架构,左下角的MASA Blazor主要是为我们去集成一个多端的UI能力,具体的使用场景将在实践篇为大家介绍——MASA Blazor如何去做多端的

接着就是集成非业务能力的MASA Framework,它主要是解决整个云原生架构中非业务性的问题

在这两个基础上,我们就可以去编写业务代码,业务代码完成后上传GitHub并发布到微服务的集群里面,而MASA Stack则是提供的平台管理能力

最右边的第三方系统管理是最关键的一部分,我们第三方系统调用是通过Dapr来管理,不难看到MASA Framework和Dapr有部分重叠,MASA Framework对Dapr进行二次封装,既可以让大家体验类似.Net原生操作,又可以作为适配层对Dapr进行替换

MASA Stack 平台架构

图片

研发协作平台:更多的是去帮助大家解决在研发过程当中的一些协作类的问题

现代化应用治理平台:主要是帮助大家解决在应用层面的一些治理问题

可观测性平台:解决的是一些可观测问题,在平台工程里面,帮助大家去采集一些公共的日志、跟踪、指标、数据等等

数据开发平台:在MASA Stack 平台里是非常重要的一个环节,在1.0和2.0中的工作主要是作为3.0的基建,为3.0做铺垫

低代码开发平台:解决API侧的编排问题,更多的还是偏开发,针对IT开发者,并不傻瓜化

集成平台:解决系统集成间的一些问题

MASA Stack 功能架构

图片

MASA Stack的功能架构底部的内容已经在前面介绍过,那我们来看下上面的内容

第一部分是研发管理部分,紧接着是现代化应用开发治理,这里面可以看到比如API网关、应用治理这些功能。第三部分数据开发与治理,是数据开发相关的内容。最后一个是可观测性,从功能结构上来说,MASA Stack1.0是其中的基础部分,但未来的3.0我们还会继续往里面补充内容,追加新的功能,并不局限于这四个版块

设计理念

图片

能力:单体/分布式皆可

配置:可配置但约定优于配置

开放:可二开,可对接,也可以任意替换

标准:面向API和SDK编程

组合:通过对能力的组合,形成专属平台

应用现代化

平台工程

图片

01 价值

为了帮助开发人员、数据科学家和终端用户,并减少他们从事有价值工作的阻力,平台工程优化了开发者体验并加速数字交付

02 如何优化开发者体验

提供一套精心策划的工具、功能和流程。减少开发者的认知负担,并包含开发团队需要的一切,以最适合他们的工作流程呈现

支持的业务策略:创建安全的底座、加速数字化、吸引和留住人才

03 关键

先构建内部开发者门户,这是最成熟、最容易理解的平台类型。积累的经验可以扩展到其他平台,平台必须将安全性嵌入到工作流程。全面、自动化的安全性和合规性检查作为测试套件的一部分,不要指望商业的一站式解决方案,无论如何你都需要定制它

MASA Stack 全景

图片

MASA Stack全景主要分为两大部分,MASA Stack每个版本是如何融合在一起的,它们之间的关系是什么?在这张图里都有清楚的展示

图中左边这一部分更贴近现代化应用部分,右边则是可观测性部分,在MASA Stack 1.0我们做的更多是一些基建类的东西,为后续版本打基础

2.0是图上白色部分,例如左下角的Workflow;3.0是图上不明显的灰色部分,比如左下角的Function,这些都是正在搭建的功能,会随着版本更新逐步实现

MASA Blazor

图片

MASA Blazor适用于PC端和移动端,包含两个库,第一个就是Blazor Component,主要提供了一个不包含样式的纯交互的组件库,第二个MASA Blazor 是基于Vuetify一个Material Design的组件库

MASA Framework

图片

Building Blocks >>接口&能力>>提供非业务能力的接口,并提供组合多个能力形成新的能力的最佳实践

Contrib>>实现>>基于构建块的接口标准提供最佳实践,可被替换实现

Utils>>通用类库>>底层通用能力,可被用于业务和Contrib

Templates>>模板>>用于创建项目

项目管理

图片

MASA PM是一款底层基建项目管理产品,提供0-1初始化的部分内容。从最初的底层环境创建,部署和创建对应的集群。编辑环境与集群的组合关系,在所需求的环境集群上创建项目。

权限中心

图片

MASA Auth是MASA Stack中最核心的功能之一,它统一负责了所有产品的权限、菜单、用户等。它包含了单点登录、用户管理、RBAC3、第三方平台接入、Ldap等企业级功能。除了可以用在企业内部管理系统,它还可以帮助管理C端用户。

配置中心

图片

MASA DCC是MASA Stack1.0推出的分布式配置中心,在整个MASA Stack产品中担任所有系统以及部分全局综合配置的功能。

消息中心

图片

MASA Stack 1.0 系统合集中底层支持消息发送的一款综合性产品,担任了全局消息系统支持多渠道的配置与消息发送规则的配置,并且可以配置多种消息模板以及特定用户组群。可以与关联产品Alert、TSC等对接,一站式解决故障问题触发与处理。

调度中心

图片

Scheduler是MASA Stack 1.0推出的一款辅助性软件产品,主要负责处理应用程序任务执行的调度,以及自动重试等相关操作。在MASA Stack产品中,与MASA MC、MASA TSC、MASA Alert 3款产品结合,发挥最大的调度价值。当然Scheduler并不只是给MASA Stack产品使用,它同样可以为业务创造价值。

故障排查控制台

图片

MASA TSC主要负责对MASA整个系统中的项目/应用进行监测来排查故障情况,其中包含从项目维度视角来查看监测的故障情况。以及溯源到具体的链路日志中去。除了可以监控整个MASA Stack的产品外,与PM进行组合使用,也可以将业务系统接入进来统一管理。

告警中心

图片

MASA Alert是一款配合性产品,主要提供告警规则以及制定相关指标。它需要借助几个产品的基础功能组合来发挥它的价值,比如故障排查控制台作为监测数据源,调度中心作为调度周期控制,消息中心作为发送消息的渠道。MASA Stack会尽可能的复用基础功能,而不是重复性工作,所以单一部署它将失去意义,产品结合可以发挥告警中心的最大价值。

文档中心

图片

MASA Stack 1.0 的文档将统一放在文档中心里,目前是比较早期的文档内容,我们会在1.0前继续完善它

优势

图片

成本低:统一技术栈、统一交互、免费

不卡脖子:技术自主可控、云原生、开源

一站式:网页端、桌面端、微服务、云、移动端、IoT、ML、游戏

集成强:平台无边界、不限制开发语言、提供API和SDK

体系完善:应用交付、数据治理、安全智能、领域最佳实践

如何开始

安装MASA Stack – Helm

图片

介绍了那么多,那我们如何开始使用MASA Stack呢?

这里我们分为两部分进行讲解,第一部分是MASA Stack的安装和接入

安装MASA Stack我们提供了Helm,首先需要准备K8s集群,有了集群后就可以创建namespace(这一步是可选项,也可以选择不创建),然后创建一个strong class(部署环境要求),部署Dapr搭建环境,使用MASA Stack Helm安装

代码也是比较简单的

helm repo add masastack https://github.com/masastack/helm
helm repo update
helm search repo masastack –devel –versions
helm upgrade –install  masastack masastack/masastack –version=xxx –namespace masastack –create-namespace –wait

虽然安装步骤简单,但实际上对K8s是要一些技术要求的,如果对K8s不是很熟悉的话,门槛相对来说还是比较的高的,之后我们也会录制MASA Stack相关的安装教程视频给大家

接入MASA Stack

图片

如果你是.NET用户,我们提供了SDK,直接接入即可

如果你是其他语言用户,我们现阶段是没有SDK的,可以通过标准的API去对接

异构

图片

如果你的项目是一个异构的,里面有不同的语言那怎么办呢?

其实可以通过Dapr的方式去做,如果它提供了SDK,可以根据的原有的SDK去调整。如果没有,可以按照图上这个标准接口去实现对接

Windows 本地开发环境

图片

接下来是基于MASA Framework的开发,首先在我们的Windows本地开发环境里面,绝大数步骤都是可选的,但如果你用的是Dapr,还是希望可以选择完整的流程去开发项目

安装WSL→安装Docker→安装Dapr,这里都是为了安装Dapr做准备

准备工作完成后就是创建项目,这一步可以使用我们的模板或者从零开始都没有问题,然后需要添加Masa.Contrib.Development.DaprStarter.AspNetCore 包,

最后一步就是在Program.cs 添加代码

#if DEBUG

builder.Services.AddDaprStarter();

#endif

它可以帮你去管理Dapr的一个生命周期

基于模板创建新项目

图片

基于模板创建新项目这一部分需要先安装MASA模板

dotnet new install Masa.Template

然后使用 MASA Framework Project 模板去创建项目,这过程中会有一些引导,去引导你去选择哪些选项(右图所示),按需勾选即可,这个阶段就是我们在自定义我们整个项目的结构,最后创建即完成

老项目对接

图片

如果是老项目对接怎么办?这里有四种方式可选

用的比较多的是HTTP,可以用MASA Framework Caller或者HttpClient去对接

第二个是gRPC,这里需要注意的是,MASA Framework Caller (2.0)才能实现对gRPC的支持,现阶段使用的比较多的Grpc.Net.Client

最后一个就是Dapr,我们的Caller提供了Dapr的全集合

这三种方式里Caller都出现了,如果说你的项目比较复杂,可能用了不同的协议,还是更推荐Caller,因为Caller是我们的一个构建块,它是面对接口的方式去编程的,不管你对接哪一种方式,只需要调换Contrib包,书写方式没有特别大的区别

以上三种方式是大家比较常见的,最后一种方式是还在开发中的MASA Stack 2.0 集成平台,在2.0里,我们会做一个集成平台,它会帮大家去接管内外的应用,HTTP、gRPC、Dapr在我们的集成平台里面都可以快速接进来

扫码观看回放

图片


如果你对我们的开源项目感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

  • WeChat:MasaStackTechOps

作者:京东零售 常文标

商卡聚合服务是一个小巧的rpc应用,功能是统一查询商品的促销、自营包邮、价格信息、区域库存、区域可配送等等利益点或其他信息。本文重点分享商卡聚合服务的代码设计,包括合理的Sirector线程调度(cpu使用率低),和可维护性的设计。 简版代码示例如下: git@github.com:changwenbiao/demosoa.git 

代码使用sirector-core组件并行调度(使用线程并行执行EventHandler的onEvent方法)请求上游rpc接口获取各利益点或其他商品信息。因为请求上游有些通用处理逻辑比如ump监控、调用开关等,所以抽象出一个通用的EventHandler名为AbstractBenefitHandler。具体调用利益点的实现类只需继承AbstractBenefitHandler并重写其抽象方法。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

接下来重点讲代码如何节省cpu使用率和易于维护的设计。

1.如何节省cpu

AbstractBenefitHandler提供isSwitchOn方法,用于决定是否使用sirector组件分配线程执行调度EventHandler。相对于分配线程执行全部的EventHandler,判断是否需要调用才分配线程调用的方式可有效减少线程调度从而减少cpu使用率。isSwitchOn方法中可加入cms控制开关逻辑比如使用ducc开关,也可加入根据用户参数判断开关的逻辑,比如查询区域库存需要四级地址,若用户不传四级地址则关闭调用EventHandler(请求上游rpc)。代码实现如下:其中ducc开关在父类中的isSwitchOn中实现,sirector.begin方法接受可变参数列表参数,可将List<AbstractBenefitHandler>转化为AbstractBenefitHandler[]作为入参。



2. 如何容易维护

减少一些模版代码(如ump监控):所有Handler的实现类的ump监控都写在父类中的onEvent中,父类的onEvent调用子类实现的onEvent0(处理具体利益点rpc请求处理)方法。

短小代码的实现:AbstractBenefitHandler提供fillResponseInfo方法以向“ResponseVO”中填数据,具体填利益点数据的代码则由相应handler实现类处理。因此各个handler填充利益点“ResponseVO”的代码都是短小的,避免了代码写在一起的长代码。单个handler填充利益点数据和批量统一填充利益点数据代码分别如下:



减少一些硬编码:handler实现类配置为原型模式(scope=”prototype”)的spring bean,通过applicationContext.getBean方法统一获取,避免一些创建(new关键字)具体实现类的代码,若新增利益点调用只需编码AbstractBenefitHandler实现类并配置为spring bean即可。批量获取handler代码如下


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在介绍 Scalar Function(给 Databend 添加 Scalar 函数 | 函数开发系例一) 后,我们来看 Aggregate Function。

Aggregate Function 用于对列的值进行操作并返回单个值。常见的 Agg Function 有 sum, count, avg 等。

函数注册

Agg Function 的 register 函数以小写的函数名和 AggregateFunctionDescription 类型为参数,每个被注册的函数都存入 case_insensitive_desc ( HashMap 结构) 中。

而 case_insensitive_combinator_desc 是为了存储一些组合函数,比如与 组合的 , 这类函数。


每个被注册的函数都要实现 trait AggregateFunction 和 AggregateFunctionFeatures。其中 AggregateFunctionFeatures 和 Scalar 中的 FunctionProperty 比较类似,都是存储函数的一些特质。


主要来看 trait AggregateFunction,这里面是 Agg Function 的构成。

函数构成

可以看到与 Scalar 直接使用一个 Struct 不同,[AggregateFunction](https://github.com/datafuselabs/databend/blob/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/src/query/functions/src/aggregates/aggregate_function.rs) 是一个 trait。因为聚合函数是按 block 累加列中的数据,再累加过程中会产生一些中间结果。

因此 Aggregate Function 必须有初始状态,而且聚合过程中生成的结果也要是 mergeable (可合并) 和 serializable (可序列化) 的。

主要函数有:

  • name 表示被注册的函数的名字,比如 avg, sum 等等。

  • return_type 表示被注册的函数返回值的类型,同样的函数返回值可能会由于参数类型的不同而产生变化。比如 sum(int8) 参数为 i8 类型,但是返回返回值可能是 int64。

  • init_state 用来初始化聚合函数状态。

  • state_layout 用来表示 state 在内存中的大小和内存块的排列方式。

  • accumulate 用于SingleStateAggregator。也就是着整个块可以在单个状态下聚合,没有任何 keys。比如 select count(*) from t 此时查询中没有任何分组列的聚合,这时会调度 accumulate 函数。

  • accumulate_keys 则是用于 PartialAggregator。这里需要考虑 key 和 offset ,每个 key 代表一个唯一的内存地址,记为函数参数 place。

  • serialize 将聚合过程中的 state 序列化为二进制。

  • deserialize 从二进制反序列化为 state。

  • merge 用于合并其他 state 到当前 state。

  • merge_result 可以将 Aggregate Function state 合并成单个值。

示例

以 avg 为例

具体实现在 [aggregate_avg.rs](https://github.com/datafuselabs/databend/blob/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/src/query/functions/src/aggregates/aggregate_avg.rs) 中。

因为我们需要累加每个值,并除以非 null 总行数。因此 avg function 被定义为 struct AggregateAvgFunction<T, SumT> 。其中 T 和 SumT 是实现 [Number](https://github.com/datafuselabs/databend/blob/2aec38605eebb7f0e1717f7f54ec52ae0f2e530b/src/query/expression/src/types/number.rs) 的逻辑类型。

在聚合过程中 avg 会产生的中间状态值是 已经累加的值的总和 以及 已经扫描过的非 null 的行。因此 AggregateAvgState 可以被定义为如下结构。


  • return_type 设置为 Float64Type。比如 value = 3, count = 2, avg = value/count。

  • init_state 初始状态设置 value 为 T 的 default 值,count 为 0。

  • accumulate AggregateAvgState 的 count, value 分别对 block 中非 NULL 的行数和值进行累加。

  • accumulate_keys 通过 place.get::<AggregateAvgState<SumT>>() 获取对应的状态值,并进行更新。


类似的聚合函数示例也可以参考

[sum](https://github.com/datafuselabs/databend/blob/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/src/query/functions/src/aggregates/aggregate_sum.rs),

[count](https://github.com/datafuselabs/databend/blob/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/src/query/functions/src/aggregates/aggregate_count.rs)。

函数测试

Unit Test

聚合函数相关单测试在 [agg.rs](https://github.com/datafuselabs/databend/blob/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/src/query/functions/tests/it/aggregates/agg.rs) 中。

Logic Test

Functions 相关的 logic 测试在 [tests/logictest/suites/base/02_function/](https://github.com/datafuselabs/databend/tree/d5e06af03ba0f99afdd6bdc974bf2f5c1c022db8/tests/sqllogictests/suites/query/02_function) 中。

关于 Databend

Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。

  • Databend 文档:https://databend.rs/

  • Twitter:https://twitter.com/Datafuse_Labs

  • Slack:https://datafusecloud.slack.com/

  • Wechat:Databend

  • GitHub :https://github.com/datafuselabs/databend

Google 于今天发布了 Android 14 的首个开发者预览版,这一发布时间与以往的发布时间类似,预计 Android 14 正式版将于今年第三季度推出。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

支持多用户登录

一家人共用同一个设备的情况十分常见,尤其是共用平板电脑。除此之外,有些用户还可能会为了 “工作” 和 “生活” 两种使用场景分别创建两个用户。

在 Android 14 的首个开发者预览版中,Google 为 Android 添加了多用户模式,可以为不同场景或者不用用户创建用户。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

应用双开(Cloned Apps)

国内不少 Android 厂商都会在手机中内置应用双开功能,方便用户同时登录一个软件的多个帐户(例如不少人喜欢的微信双开)。

通过 Android 14 Developer Preview 1,Google 也正在准备一种官方方式来 “克隆” 应用程序,而无需借助任何第三方应用程序。现在只需前往新的 “Cloned Apps” 菜单,并选择想要克隆的 Android 应用程序即可。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

双 SIM 卡支持自动切换移动数据到最佳选项

Android 14 中,Google 增加了双卡双待自动切换到最佳移动数据选项的功能。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

屏幕时间

在 Android 14 的首个开发者预览版中,Google 重新设计了电池使用页面,突出显示 “自上次充满电以来的屏幕使用时间” 部分。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

任务栏

在 Android 14 首个开发者预览版中,当用户切换到平板电脑时,任务栏现在会在应用程序图标下方显示文本名称。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

字体

用户现在可以在 Android 14 中将字体大小最多缩放 200%,而 Android 13 最多可缩放 130%。Google 还将使用非线性字体缩放,这样已经很大的文本就不会再进一步增大了。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Android API

Google 调整了两个 Android API(前台服务和作业调度程序),以提高后台活动和下载大文件等任务的效率。

时间表

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

根据官方发布的时间表,Google 将会发布两个开发者预览版、四个测试版,最终版本有望在今年第三季度正式发布。

Android 14 的开发者预览版目前适配于以下设备:Pixel 4a(5G)、Pixel 5、Pixel 5A 5G、Pixel 6、Pixel 6 Pro、Pixel 7 和 Pixel 7 Pro。

更多详情可查看:https://android-developers.googleblog.com/2023/02/first-developer-preview-android14.html

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Rust通用代码生成器:莲花公布第一个尝鲜版, 支持前端,支持Excel,PDF数据前端

Rust通用代码生成器莲花公布第一个尝鲜版。此版本支持Excel,PDF数据导出。支持Vue,ElementUI的独立前端。支持MySQL,MariaDB和PostgreSQL数据库。支持图片功能。支持所附全部非Oracle示例。欢迎试用。

介绍视频请参考:

https://www.bilibili.com/video/BV1jy4y1R79h/

Rust语言通用代码生成器:莲花,已发布尝鲜版, 此版本支持 PostgreSQL 数据库。完善支持图片功能。支持全部所附示例。现在支持 MariaDB,MySQL,PostgreSQL 三种数据库。支持Excel,PDF数据导出。支持Vue,ElementUI的独立前端。在最近的开发中,全部已支持所附非 Oracle 示例的功能,包括图形报表和复杂版面功能也已经支持。欢迎广泛测试并反馈。此版本尚未支持弹性登录模块和 Oracle 数据库,敬请期待新版本。

代码生成器的项目地址:https://gitee.com/jerryshensjf/Lotus

二进制 war 包的下载地址: https://gitee.com/jerryshensjf/Lotus/attach_files

Rust通用代码生成器:莲花

介绍

Rust通用代码生成器:莲花

软件架构说明

软件使用Java写成,部署在Tomcat 9的webapps目录中。

本软件是从Go语言通用代码生成器:仙童尝鲜版十二改写而来。

代码生成物是rust 1.65环境。采用Axum 0.4.8 , tower web框架,tokio 1.0 , sqlx 0.3.5数据库访问层和MariaDB, MySQL 8,PostgreSQL数据库。

目前代码生成器已发布第一个尝鲜版。您可以使用所附非Oracle示例测试系统,可以得到可以运行的代码生成物。

尝鲜版支持Excel,PDF数据导出。支持Vue,ElementUI的独立前端。支持MySQL,MariaDB和PostgreSQL数据库。支持图片功能。支持所附全部非Oracle示例。欢迎试用。

百度话题

#通用代码生成器#

介绍视频

https://www.bilibili.com/video/BV1jy4y1R79h/

尝鲜版版下载

https://gitee.com/jerryshensjf/Lotus/attach_files

项目图片

输入图片说明

输入图片说明

软件截屏

输入图片说明

输入图片说明

代码生成物截屏

单表操作

输入图片说明

多对多

输入图片说明

复杂版面,树表

输入图片说明

图形报表

输入图片说明

图片功能

输入图片说明

参考例程

可以参考例程GirlOnlyTower,请见:

https://gitee.com/jerryshensjf/GirlOnlyTower

 

 

 

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

前言:BeikeShop作为开源电商建站系统,我们有必要向各位开发者同步我们未来一年的开发计划!

今天,我们一次性将全年的开发计划Roadmap 公布出来,希望各位开发者根据自身的需求,共同决策BeikeShop未来的发展方向!!

 

BeikeShop是什么?——BeikeShop是一款开源好用的跨境电商系统!

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

BeikeShop能够帮助卖家,快速的搭建属于自己的独立站,让卖家快速的进行国际网站建站——系统完全开源免费可商用!

 

✦✦

Roadmap 开发计划

本开发计划可能会根据用户的使用需求,以及开发者反馈的情况,提前或延后部分功能的开发时间节点!

此外Roadmap计划中,如果没有您需要的功能,欢迎你积极留言反馈,我们会评估后,将其添加到开发计划中

v1.3 – 2023年02月

1. 开发文档完善

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

文档的完善,可以帮助开发者更高效的进行开发。

后续,我们会根据开发者在交流群中提出的疑问,不断的完善docs文档!

 

文档地址:

https://docs.beikeshop.com/

 

2. 代码优化 + 格式 + 命名

代码的优化和标准化,能保证beikeshop系统的代码具有良好的可读性。同时也可以提升协同开发的效率,降低沟通成本

 

3. 子商品 SKU 批量操作

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

让卖家可以更快速的创建多规格商品

 

4. Blade 模板修改插件化

Blade模板插件化修改,采用 Hook 方式实现, 可以让开发者在不修改系统原文件的基础上轻松修改模板

结合插件数据Hook(Filter) 和 流程Hook(Action), 方便开发功能强大的各种插件!

 

5. 客户组折扣

根据用户提出的需求,同一个分组的用户,可以获得设定的折扣比率,目前规划的是针对商城全部商品有效

 

6. 自动化测试脚本

覆盖:Base、首页、模块、注册、登录功能

 

v1.4 – 2023年03月

 

1. 子商品快速生成优化

根据v1.3版本中,卖家使用时反馈的问题,进一步优化该功能

 

2. 自动化测试脚本

覆盖:分类、品牌、搜索、筛选、产品模块功能

 

 

v1.5 – 2023年05月

 

1. 邮件订阅

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

帮助使用BeikeShop开源系统的跨境独立站卖家,通过EDM更好的维护客户关系,促成商品销售!

 

2. 商品评论

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

用户反馈,该功能是海外独立站最常用到的功能。常见的商品评论模式有购买后评论”和“非购买留言”两种

 

3. 自动化测试脚本

覆盖:前台API、购物车、结账页、商品评论功能

 

v1.6 – 2023年07月

 

1. 前台开放API && KEY生成

其中包括:注册、登录、购物流程、个人中心、订单

 

2. 自动化测试脚本

覆盖:后台API、个人中心、订单、收藏

 

 

v1.7 – 2023年08月

 

1. 后台开放API

其中包括:产品、品牌、分类、客户、订单管理

 

2. 商品采集浏览器插件

计划可采集:aliexpres、1688、京东、淘宝、天猫、天猫国际、天猫超市

由于采集插件的采集规则,需要频繁的维护更新,可能会开发为收费或订阅模式的插件模式!

 

3. Facebook Pixel

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

 

v1.9 – 2023年10月

 

1. 后台一键升级

版本升级包 + DB Migrate + Composer

 

v2.0 – 2023年12月

 

1. 对象存储:

AWS兼容(AWS+阿里云+腾讯云+七牛)

 

2. Tiktok对接

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

3. 商城统计报表

针对跨境独立站卖家的数据分析需求,专门搭建的统计报表工具

未来可能以API或hook的模式,让卖家可以通过第三方分析工具,对店铺经营情况进行分析

 

如果有想要开发的其他功能 或 任何想法,欢迎留言交流!

 

介绍

UiAdmin 是一套零前端代码通用后台,采用前后端分离技术,数据交互采用 json 格式;通过后端 Builder 不需要一行前端代码就能构建一个 vue+element 的现代化后台;同时我们打造一了套兼容性的 API 标准,从 SpringBoot、ThinkPHP 开始,逐步覆盖.net、nodejs等多语言框架。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

更新日志

UiAdmin项目创立之初就确定了多语言同步统一发展的方向,在PHP/JAVA/.net版本已经发布基础上,本次新增Python&NodeJS两个全新语言版本,引入依赖包即可使用,适用于新老项目,无代码侵入。详情如下,Builder相关文档可先参考别的语言版本,接口保持完全统一。

Python版本

说明

python版本uiadmin实现, API接口自动生成管理后台,无需前端参与。

教程

安装依赖

 pip install Flask pip install uiadmin-flask

app.py使用

 from flask import Flask from flask_cors import CORS from uiadmin_flask.Uiadmin import Uiadmin from uiadmin_flask.util import jsonres from uiadmin_flask.util.xybuilder.XyBuilderList import XyBuilderList from uiadmin_flask.util.xybuilder.XyBuilderForm import XyBuilderForm app = Flask(__name__) # 调用Uiadmin uiadmin = Uiadmin(app) app.config.update( UIADMIN_SITE_TITLE='UiAdmin', // 后台名称 UIADMIN_SITE_LOGO='', // logo UIADMIN_SITE_LOGO_BADGE='Beta' // 角标 ) cors = CORS(app, resources={r"/*": { "origins": "*", "allow_headers": "Authorization, Content-Type, CloudId, Eid", "methods": "GET, POST, PUT, DELETE, OPTIONS" }}, supports_credentials=True) @app.route("/") def index(): return "<a href='https://www.xujun.org/xyadmin/'>打开后台</a>" # 示例 @uiadmin.menu_item({"title": "文章列表", "path": "/demo/lists", "pmenu": "/content", "menuType": 1, "routeType": "list", "apiSuffix": "", "apiParams": "", "apiMethod": "GET", "sortnum": 0}) @app.route("/api/v1/admin/demo/lists") def demo_lists(): dataList = [ { "id": 1, "title": "测试文章1", "cate": "开发", "cover": "https://ts2.cn.mm.bing.net/th?id=ORMS.11d30098d0f4a79a42c6352014e0f066&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=2&p=0", "level": 1, "progress": 50, "updateTime": "2023-02-01 20:16:19", "createTime": "2023-02-01 09:07:40", "status": 1 }, { "id": 2, "title": "测试文章2", "cate": "开发", "cover": "https://ts2.cn.mm.bing.net/th?id=ORMS.ed34ae135a326a834ca9d3379be134d3&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=2&p=0", "level": 2, "progress": 80, "updateTime": "2023-02-01 20:16:19", "createTime": "2023-02-01 09:07:40", "status": 1 }, { "id": 3, "title": "测试文章3", "cate": "科技", "cover": "https://ts2.cn.mm.bing.net/th?id=ORMS.ed34ae135a326a834ca9d3379be134d3&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=2&p=0", "level": 3, "progress": 90, "updateTime": "2023-02-01 20:16:19", "createTime": "2023-02-01 09:07:40", "status": 1 }, ] xyBuilderlist = XyBuilderList(); (xyBuilderlist .init() .addColumn("title", "标题", { "type": "text" }) .addColumn("cover", "封面", { "type": "image", }) .addColumn("cate", "分类", { "type": "tag", "prefixType": "dot", "options": [] }) .addColumn("progress", "进度", { "type": "progress" }) .addColumn("level", "评分", { "type": "rate" }) .addColumn("level", "优先级", { "prefixType": "dot", "useOptions": True, "options": [ {"title": "低", "value": 1, "color": "#c6cdd4"}, {"title": "中", "value": 2, "color": "#0488de"}, {"title": "高", "value": 3, "color": "#ff9d28"} ] }) .addColumn("createTime", "创建时间", { "type": "time", }) .addColumn("updateTime", "发布时间", { "type": "time", }) .addTopButton("add", "添加", { "title": "新增", "pageType": "modal", "modalType": "form", "api": "/v1/admin/demo/add", "width": "1000px" }) .addColumn("rightButtonList", "操作", { "type": "rightButtonList", "minWidth": "120px" }) .addRightButton("edit", "修改", { "title": "修改", "pageType": "modal", "modalType": "form", "api": "/v1/admin/demo/edit", "width": "1000px" }) .setDataList(dataList) ) return jsonres({ "code": 200, "msg": "登录成功", "data": { "listData": xyBuilderlist.getData() } } ) @uiadmin.menu_item({"title": "文章增加", "path": "/demo/add", "pmenu": "/demo/lists", "menuType": 1, "routeType": "form", "apiSuffix": "", "apiParams": "", "apiMethod": "POST", "sortnum": 0}) @app.route("/api/v1/admin/demo/add") def demo_add(): xyBuilderForm = XyBuilderForm() (xyBuilderForm .init() .addFormItem("name", "文章标题", "text", "", {}) .addFormItem("content", "文章内容", "html", "", {}) .addFormItem("level", "登记", "select", "", { "options":[ {"title": "低", "value": 1}, {"title": "中", "value": 2}, {"title": "高", "value": 3}, ] }) ) return jsonres({ "code": 200, "msg": "成功", "data": { "formData": xyBuilderForm.getData() } } ) @uiadmin.menu_item({"title": "文章修改", "path": "/demo/edit", "pmenu": "/demo/lists", "menuType": 1, "routeType": "form", "apiSuffix": "", "apiParams": "", "apiMethod": "POST", "sortnum": 0}) @app.route("/api/v1/admin/demo/edit/<string:id>") def demo_edit(id): xyBuilderForm = XyBuilderForm() (xyBuilderForm .init() .addFormItem("id", "ID", "text", "", { "disabled": True }) .addFormItem("name", "文章标题", "text", "", {}) .addFormItem("content", "文章内容", "html", "", {}) .addFormItem("level", "登记", "select", "", { "options":[ {"title": "低", "value": 1}, {"title": "中", "value": 2}, {"title": "高", "value": 3}, ] }) .setFormValues({ "id": id, "name": "text", "content": "测试", "level": 2 }) ) return jsonres({ "code": 200, "msg": "成功", "data": { "formData": xyBuilderForm.getData() } } ) if __name__ == '__main__': app.run(host='0.0.0.0', debug=True)

运行

 export FLASK_APP=app flask run 

 

NodeJS版本

 

简介

uiadmin的nodejs-express实现版本

使用步骤

安装

 

配置babel

babel.config.js文件增加如下配置 注意删除.babelrc

 

配置启动

package.json配置如下命令,其中app为你的express应用入口。

 

初始化

app.js请参考如下代码

 

app.listen(port, () => { console.log() })

启动

 

访问{host:端口}/xyadmin/

开发

仿照DemoController进行业务开发

春节刚过, 便迎来了 版本。此次发布内容,共有 个 , 位贡献者的参与。新增了若干功能,修复了 ,优化了若干内容。

新功能

  1. 添加 插件
  • 在网关中引入 插件 引入网关对 的代理插件,在网关的 文件中增加如下依赖:
 
  • 服务接入网关

    在由 构建的微服务中,引入如下依赖:

 
  • 在 配置文件增加如下配置:
 

关于 插件的更多使用请参考

https://shenyu.apache.org/zh/docs/plugin-center/proxy/brpc-plugin

  1. 支持不同命名空间

具体实现请参考: https://github.com/apache/shenyu/pull/4258

  1. 优化 插件

具体实现请参考:https://github.com/apache/shenyu/pull/4256

  1. 注册中心实例支持

具体实现请参考:https://github.com/apache/shenyu/pull/4144

  1. 支持 文档

具体实现请参考: https://github.com/apache/shenyu/pull/4263

  1. 添加 插件的规则处理参数

具体实现请参考:https://github.com/apache/shenyu/pull/3982

  1. 添加 测试引擎 支持的 测试。

具体实现请参考:https://github.com/apache/shenyu/pull/3942

  1. 添加 插件支持

具体使用请参考:https://shenyu.apache.org/zh/docs/plugin-center/security/casdoor

  1. 添加 插件 该插件用于支持收集日志到日志平台,并通过日志平台进行数据分析。

具体使用请参考:https://shenyu.apache.org/zh/docs/plugin-center/observability/logging-tencent-cls

  1. 添加 插件

具体实现请参考: https://github.com/apache/shenyu/pull/3832

  1. 添加 插件

    通过收集网关请求日志,通过其他应用消费消息,并且对日志进行分析。

    架构图:

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    插件使用流程图

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

具体使用请参考: https://shenyu.apache.org/zh/docs/plugin-center/observability/logging-pulsar

  1. 添加 插件

具体实现请参考:https://github.com/apache/shenyu/pull/3756

增强

  1. 优化 客户端注解

具体实现请参考:https://github.com/apache/shenyu/pull/3889

  1. 优化插件配置

具体实现请参考: https://github.com/apache/shenyu/pull/3851

  1. 优化 客户端注解

具体实现请参考:https://github.com/apache/shenyu/pull/3853

  1. 优化 客户端注解

具体实现请参考: https://github.com/apache/shenyu/pull/3819

  1. 优化 客户端注解

具体实现请参考:https://github.com/apache/shenyu/pull/3819

重构

  1. 重构 文档的请求

具体实现请参考:https://github.com/apache/shenyu/pull/4311

  1. 重构 插件

具体实现请参考:https://github.com/apache/shenyu/pull/3832

  1. 优化 相关依赖

具体实现请参考:https://github.com/apache/shenyu/pull/4289

  1. 重构 插件

具体实现请参考:https://github.com/apache/shenyu/pull/4304

  1. 更新

具体实现请参考:https://github.com/apache/shenyu/pull/4259

  1. 移除不必要的单例

具体实现请参考:https://github.com/apache/shenyu/pull/4230

  1. 修复并发场景数据

具体实现请参考:https://github.com/apache/shenyu/pull/4229

  1. 重构 测试

具体实现请参考:https://github.com/apache/shenyu/pull/4226

  1. 重构

具体实现请参考:https://github.com/apache/shenyu/pull/4217

  1. 重构 规则

具体实现请参考:https://github.com/apache/shenyu/pull/4210

  1. 优化

具体实现请参考:https://github.com/apache/shenyu/pull/4205

  1. 优化缓存

具体实现请参考:https://github.com/apache/shenyu/pull/4197

  1. 修复

具体实现请参考:https://github.com/apache/shenyu/pull/4155

  1. 修复 数据同步

具体实现请参考:https://github.com/apache/shenyu/pull/4141

  1. 重构 客户端

具体实现请参考:https://github.com/apache/shenyu/pull/4130

  1. 优化请求超时

具体实现请参考:https://github.com/apache/shenyu/pull/4070

  1. 重构日志模块

具体实现请参考:https://github.com/apache/shenyu/pull/3917

  1. 重构 客户端

具体实现请参考:https://github.com/apache/shenyu/pull/4001

  1. 重构 插件

具体实现请参考:https://github.com/apache/shenyu/pull/3959

  1. 重构 数据同步

具体实现请参考:https://github.com/apache/shenyu/pull/3940

  1. 重构 客户端

具体实现请参考:https://github.com/apache/shenyu/pull/3938

  1. 重构 客户端

具体实现请参考:https://github.com/apache/shenyu/pull/3935

  1. 重构 客户端

具体实现请参考:https://github.com/apache/shenyu/pull/3931

  1. 重构 配置

具体实现请参考:https://github.com/apache/shenyu/pull/3918

  1. 优化随机算法

具体实现请参考:https://github.com/apache/shenyu/pull/3911

  1. 重构负载均衡算法

具体实现请参考:https://github.com/apache/shenyu/pull/3890

  1. 重构 插件

具体实现请参考:https://github.com/apache/shenyu/pull/3885

错误修复

  1. 移除多余的 设置

具体实现请参考:https://github.com/apache/shenyu/pull/4283

  1. 修复 删除逻辑

具体实现请参考:https://github.com/apache/shenyu/pull/4268

  1. 修复 插件

具体实现请参考:https://github.com/apache/shenyu/pull/4267

  1. 修复 插件

具体实现请参考:https://github.com/apache/shenyu/pull/4260

  1. 修复升级脚本

具体实现请参考:https://github.com/apache/shenyu/pull/4194

  1. 修复 注册空指针问题

具体实现请参考:https://github.com/apache/shenyu/pull/4176

  1. 修复 解析

具体实现请参考:https://github.com/apache/shenyu/pull/4170

  1. 修复插件更新时的异常

具体实现请参考:https://github.com/apache/shenyu/pull/4146

  1. 修复 脚本

具体实现请参考:https://github.com/apache/shenyu/pull/4091

  1. 修复 插件的异常

具体实现请参考:https://github.com/apache/shenyu/pull/3954

  1. 修复 异常

具体实现请参考:https://github.com/apache/shenyu/pull/3951

  1. 修复更新密码异常

具体实现请参考:https://github.com/apache/shenyu/pull/3898

  1. 修复选择器分页异常

具体实现请参考:https://github.com/apache/shenyu/pull/3875

  1. 修复 插件异常

具体实现请参考:https://github.com/apache/shenyu/pull/3872

  1. 修复 插件并发处理异常

具体实现请参考:https://github.com/apache/shenyu/pull/3852

  1. 修复 插件异常

具体实现请参考:https://github.com/apache/shenyu/pull/4267

  1. 修复 插件异常

具体实现请参考:https://github.com/apache/shenyu/pull/4260

贡献者

特别感谢以下贡献者对 版本的支持和参与(排名不分先后)。

dragon-zhang, zhengpeng, mahaitao, 愿凌飞, hdgaadd, dayu, SongTao Zhuan g, Misaya295 , Shawn Jim , yunlongn , Will , moremind , RayayChung , Kevin Clair , huanccwang , 柯杨 , Kunshuai Zhu , fantiq , youzipi , class , kyeongsun , 杨阳洋 , Liming Deng , 杨文杰 , xcsnx , hnxiaoyuan , dependabot , xiaoyu , wzhangNJ , Zihao Huang , ywj1352 , pandaapo , WuLang , Nineteen , kyeongsun , ableYang , Runqi Zhao , WeiS , Luke.Z , lahmxu , Sinsy , Daming , BoyuLi4 , jakiuncle , Bowen Li , huanccwang , gitchenjh , DamonXue , Wu Daifu , Jiageng , nuo-promise , Guocheng Tang , likeguo , Sixh-PrFor , throwable , renzhuyan , wangteng , qinghai777 , zly , 奕仁 , 尔等同学 , qifanyyy , Jairo , ousinka

关于Apache ShenYu

一款使用 开发的响应式 网关。以其高性能,动态灵活的流量管控,热插拔,易部署等特性,开箱即用为用户提供整套全生命周期的 网关,包含 注册、服务代理、协议转换与 治理等功能。于毕业成为顶级项目。

官网: https://shenyu.apache.org GitHub: https://github.com/apache/shenyu

成为贡献者

我们欢迎每一位贡献者的加入!

贡献者指南请参考:

https://shenyu.apache.org/zh/community/contributor-guide

Snowy-Cloud(SnowyAdmin 微服务版)是国内首个国密前后端分离快速开发平台,集成国密加解密插件, 软件层面完全符合等保测评要求,同时实现国产化机型、中间件、数据库适配,是您的不二之选! 技术框架与密码结合,让更多的人认识密码,使用密码;更是让前后分离 “密” 不可分。

采用 SpringCloud+SpringBoot+MybatisPlus+AntDesignVue+Vite 等更多优秀组件及前沿技术开发,注释丰富,代码简洁,开箱即用!

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

此次更新内容如下:

1、【更新】修复查询使用lamdaUpdateWrapper的错误
2、【更新】优化导包
3、【优化】生成代码后加入权限控制接口、修复代码生成配置部分内容被重置问题、生成的表单数字输入框值改为10000,滑动输入改为1000
4、【修复】AllPermission,权限树无法查询问题修复
5、【修复】代码生成错误修复

感兴趣小伙伴可以尝试使用,源码开源!

漏洞描述

Rancher 是一个开源容器管理平台。

由于 CVE-2021-36782 漏洞的修复不充分,Rancher 2.5.0 至 2.5.16 版本,2.6.0 至 2.6.9 及 2.7.0 版本仍存在凭据泄露漏洞,由于敏感字段、秘密令牌、加密密钥和 SSH 密钥等以明文的形式被存储在 Kubernetes 对象上(如:Clusters)经过身份验证的攻击者如:集群所有者、集群成员、项目所有者或该集群的项目成员可通过以下 api 查看公开凭据:

1、/v1/management.cattle.io.cluster

2、/v1/management.cattle.io.clustertemplaterevisions

漏洞名称 Rancher 存在凭据泄露漏洞 漏洞类型 敏感数据的明文存储 发现时间 2023-02-08 漏洞影响广度 广 MPS编号 MPS-2022-61105 CVE编号 CVE-2022-43757 CNVD编号 –

影响范围

github.com/rancher/rancher@[2.6.0, 2.6.10)

github.com/rancher/rancher@[2.5.0, 2.5.17)

github.com/rancher/rancher@[2.7.0, 2.7.1)

修复方案

将组件 github.com/rancher/rancher 升级至 2.6.10 及以上版本

将组件 github.com/rancher/rancher 升级至 2.5.17 及以上版本

将组件 github.com/rancher/rancher 升级至 2.7.1 及以上版本

参考链接

https://www.oscs1024.com/hd/MPS-2022-61105

https://nvd.nist.gov/vuln/detail/CVE-2022-43757

https://github.com/rancher/rancher/security/advisories/GHSA-cq4p-vp5q-4522

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

漏洞描述

Rancher 是一个开源容器管理平台。

Rancher 的受影响版本中由于授权逻辑缺陷导致通过 project role template binding (PRTB) 且具有 -promoted 身份的用户进行特权升级,攻击者可利用此漏洞提升任何集群中资源的操作权限。

用户可通过以下措施缓解漏洞:

1、只将项目所有者和管理项目成员角色授予受信任的用户;

2、尽量减少在 projectroletemplatebindings 资源中创建包含 escalate、* 或包含 create、delete、patch、update 的自定义角色,并仅将此类自定义角色授予受信任的用户;

3、尽可能减少有权创建、修补和更新角色模板的用户数量。

漏洞名称 Rancher 提权漏洞(基于PRTB和promoted身份) 漏洞类型 特权管理不恰当 发现时间 2023-02-08 漏洞影响广度 广 MPS编号 MPS-2022-61107 CVE编号 CVE-2022-43759 CNVD编号 –

影响范围

github.com/rancher/rancher@[2.6.0, 2.6.10)

github.com/rancher/rancher@[2.5.0, 2.5.17)

修复方案

将组件 github.com/rancher/rancher 升级至 2.6.10 及以上版本

将组件 github.com/rancher/rancher 升级至 2.5.17 及以上版本

参考链接

https://www.oscs1024.com/hd/MPS-2022-61107

https://nvd.nist.gov/vuln/detail/CVE-2022-43759

https://github.com/rancher/rancher/security/advisories/GHSA-7m72-mh5r-6j3r

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

漏洞描述

Argo CD 是一个为Kubernetes 而生的,遵循声明式GitOps 理念的持续部署工具。Argo CD 可在Git 存储库更改时自动同步和部署应用程序。

在受影响版本内,存在泄露存储库凭据漏洞,存储库凭据信息通过错误信息展示给用户并且会记录在日志中。

当用户通过 Argo CD API、UI、CLI 来创建或更新应用时,会接受到含有存储库凭据信息的错误信息。

*用户须要有创建或更新应用的 RBAC 权限才可以访问到含有存储库凭据信息的错误信息。

(RBAC 特性允许限制对 Argo CD 资源的访问。Argo CD 没有自己的用户管理系统,只有一个内置的用户管理员。管理员用户是一个超级用户,可以不受限制地访问系统。RBAC 需要 SSO 配置或一个或多个本地用户设置。一旦配置了 SSO 或本地用户,就可以定义额外的 RBAC 角色,然后可以将 SSO 组或本地用户映射到角色。)

漏洞名称 Argo CD 存在泄露存储库凭据漏洞 漏洞类型 日志敏感信息泄露 发现时间 2023-02-09 漏洞影响广度 广 MPS编号 MPS-2023-3779 CVE编号 CVE-2023-25163 CNVD编号 –

影响范围

github.com/argoproj/argo-cd@[2.6.0-rc1, 2.6.1)

修复方案

将组件 github.com/argoproj/argo-cd 升级至 2.6.1 及以上版本

参考链接

https://www.oscs1024.com/hd/MPS-2023-3779

https://nvd.nist.gov/vuln/detail/CVE-2023-25163

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

漏洞描述

opentelemetry-go 是一个用 Go 开发的 OpenTelemetry 的 API 和 SDK,opentelemetry-go-contrib 是 OpenTelemetry-Go 的扩展集合。

opentelemetry-go-contrib 0.38.0版本中,由于 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp 使用 httpconv.ServerRequest 函数为 http.server.request_content_length, http.server.response_content_length 和 http.server.duration 检测(instruments)注释指标(Metrics)测量值,由于该函数将 http.target 属性值设置为整个请求 URI(包括查询字符串),检测不会清除之前的测量属性,如果接收的查询字符串始终是随机的,这将导致内存分配不断增加,攻击者可利用此漏洞构造包含大量随机字符串的恶意请求进行拒绝服务攻击。

漏洞名称 opentelemetry-go-contrib v0.38.0 存在拒绝服务漏洞 漏洞类型 拒绝服务 发现时间 2023-02-09 漏洞影响广度 极小 MPS编号 MPS-2023-3767 CVE编号 CVE-2023-25151 CNVD编号 –

影响范围

go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@[0.38.0, 0.39.0)

go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego@[0.38.0, 0.39.0)

修复方案

将组件 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp 升级至 0.39.0 及以上版本

将组件 go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego 升级至 0.39.0 及以上版本

参考链接

https://www.oscs1024.com/hd/MPS-2023-3767

https://nvd.nist.gov/vuln/detail/CVE-2023-25151

https://github.com/open-telemetry/opentelemetry-go-contrib/security/advisories/GHSA-5r5m-65gx-7vrh

https://github.com/open-telemetry/opentelemetry-go/blob/v1.12.0/semconv/internal/v2/http.go#L159

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

欢迎 HertzBeat 新晋两位 Committer

非常高兴 Dromara HertzBeat 开源社区又迎来了两位新晋社区 Committer, 有来自一线的研发小组leader,也有来自大厂的实习生,让我们来了解下他们的开源经历吧!

第一位 进击的阿晨

姓名:高晨

现从事:帆软软件Java研发

Hertzbeat Committer

github:gcdd1993 (进击的阿晨)

初识Hertzbeat

2022年4月开始接触Hertzbeat,当时公司出现了一次宕机事故,网站无法访问,直到用户反馈才得知,急需一款能监控网站在线率,并及时告警的监控平台。浏览了几款监控平台后,最后敲定了Hertzbeat,因为它功能强大,满足需求的同时还有些惊喜,最重要的是代码规范,注释清晰,技术栈吻合,便于企业二次开发。结合强大的自定义通知,我们对数据库、中间件、网站进行了监控,对公司平台的稳定运行起到了至关重要的作用。

开始提交PR

2022年4月17日提交了第一个PR,主要是针对使用过程发现的TDEngine时区错误的问题,虽然是简单的配置修改,但是也让我更加地了解HertzBeat,并且随着对源码的深入了解,学到了很多东西。

持续的开源贡献与收获

到目前为止,参与hertzbeat开源项目已有半年多时间,贡献了许多,也成长收获了许多。具体如下:

  • 基于策略模式重构了告警模块
  • 实现了对数据库的指标监控
  • 优化 配置项
  • 实现支持了 、、 的消息通知渠道
  • 使用 重构了告警文本,告警通知模版更规范化

感谢社区小伙伴

感谢无偿帮助过我或给过我启发的小伙伴:tomsun28,在贡献过程中遇到的每一个问题,都能耐心指导。

对新人的一点建议

  • HertzBeat的源码对新人非常友好,代码规范,注释丰富,非常适合作为学习项目。
  • 开源贡献绝不是一蹴而就的,每一个想法,每一次疑问/解答都是一次贡献,迈出第一步才是最重要的!

下一位 🌻 铁甲小宝

姓名:高兴存

现从事:河南师范大学大三学生, 阿里实习

HertzBeat Committer

github:TJxiaobao

🌻 初识hertzbeat

首先要在这里感谢🙏花城师兄,因为当时自己想学习一些优秀的 项目。然后在吃饭的时候向师兄请教了一下有没有好的项目推荐,恰好这时师兄把我推荐给了tom哥。当我亲自使用了 的时候真的是发现了新的大陆,相比较于自己之前接触简单的 项目,不论是 的架构设计,还是它的实用功能都深深折服了我。此时一颗 的种子已经在我的心中种下。

🌻 开始提交PR

在 Oct 20, 2022 是我第一次提交 的时间,虽然本次 是简单的翻译注释,看着技术含量不是很高。但是他也能让我更快的熟悉项目的业务逻辑和架构设计,能为以后的贡献打下坚实的基础。而这次 也是我迈向开源的第一步,也是让我爱上开源的起点!

🌻 持续的开源贡献和收获

从第一次 到现在,参加 开源项目已经有一段时间了,也贡献了一小部分,也成长收获了很多。具体如下。

贡献:

  • 1、实现对 docker 容器的监控。
  • 2、完成 国产数据库 DM 监控
  • 3、编写相对应业务的单测。
  • 4、部分注释的英文翻译。

收获:

  • 1、技术能力得到进一步的提升。
  • 2、开阔自己的眼界。
  • 3、从大佬们身上学到了很多知识。

🌻 感谢社区小伙伴

感谢无偿帮助过我或给过我启发的小伙伴(排名不分先后):tomsun28(tom哥),花城(师兄)

🌻 对新人的一点建议

首先我也是一枚新手村的萌新啦,但是我可以把我的一些经验分享给大家,希望能给大家有所帮助。

  • 1、不要过于心急,要沉静身心了解各个模块的大致实现逻辑。
  • 2、通过使用不同的功能,并 debug 来看看各个功能的底层实现原理。
  • 3、慢慢的尝试阅读源码,并理解。
  • 4、如果遇见bug,可以直接反馈到 isses,也可以自己尝试解决嘿嘿。

What is HertzBeat?

HertzBeat赫兹跳动 是一个拥有强大自定义监控能力,无需Agent的实时监控告警系统。应用服务,数据库,操作系统,中间件,云原生等监控,阈值告警,告警通知(邮件微信钉钉飞书短信 Discord Slack Telegram)。

我们将等协议规范可配置化,只需配置YML就能使用这些协议去自定义采集任何您想要采集的指标。
您相信只需配置YML就能立刻适配一个K8s或Docker等新的监控类型吗?

的强大自定义,多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。

Github: https://github.com/dromara/hertzbeat
Gitee: https://gitee.com/dromara/hertzbeat

⛄ Supported

  • 网站监控, 端口可用性, Http Api, Ping连通性, Jvm, SiteMap全站, Ssl证书, SpringBoot, FTP服务器
  • Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, 达梦, OpenGauss, ClickHouse, IoTDB
  • Linux, Ubuntu, CentOS, Windows
  • Tomcat, Nacos, Zookeeper, RabbitMQ, Flink, Kafka, ShenYu, DynamicTp, Jetty, ActiveMQ
  • Kubernetes, Docker
  • 和更多您的自定义监控。
  • 通知支持 。

VMware云原生实验室团队在上周开源发布了联邦学习的生命周期管理项目FedLCM并贡献到LF AI & DATA基金会和FATE开源社区。

联邦学习是人工智能与数据领域中最为火热的方向之一,作为社区期待已久的项目,FedLCM从包含多个参与方的联邦的维度,借助云原生技术极大地简化了联邦学习系统部署维护和使用的复杂度,赋能跨云、跨边缘设备等场景下的联邦学习应用。本文对FedLCM的设计、功能、使用方式等进行了详细的介绍,也期待项目的开源能够进一步促进相关领域的创新发展和生产实践。

背景

随着联邦学习相关领域的研究和应用不断的发展,越来越多的用户投入到了以FATE为代表的联邦学习系统的开发和使用之中,相关社区生态也在进一步的壮大。联邦学习系统天然有着分布式的特性,部署和使用都有一定的门槛,为此,FATE社区提供了包括KubeFATE和AnsibleFATE等项目来帮助用户完成FATE系统在一个站点,即一个参与方内部的部署和运维管理等任务。而联邦学习需要有多个参与方,因此各方都需要在本方环境中进行FATE的部署安装管理,并配置各方的互联信息,才能形成一个可以运行真正训练任务的“联邦“。此外,当前的部署解决方案(包括 KubeFATE和AnsibleFATE)是基于命令行的,需要用户有一定基础知识,在进行FATE系统部署时的步骤也较为复杂,对很多用户来说仍然有一些负担。

为了应对以上挑战,并进一步降低FATE系统的使用门槛,VMware云原生实验室开发了FedLCM (Federation Lifecycle Manager)项目,并开源贡献到FATE社区。FedLCM是一个从联邦维度对FATE系统各方进行统一管理的解决方案,提供基于网页图形化界面的FATE联邦和集群部署管理平台。

FedLCM简介

A.FedLCM的基本功能

顾名思义,FedLCM的核心功能是Lifecycle Manager服务:即FATE联邦与集群部署的生命周期管理。通过使用Lifecycle Manager的图形化界面,用户可以在几分钟内轻松部署FATE Exchange以及各个参与方的FATE系统组件,如FATE-Flow、各个基础引擎等。除了简化部署流程之外,FedLCM 还包含其他生命周期管理功能,如自动更新各方的路由配置以快速组建起FATE联邦、证书签发与安装、多个联邦多个部署实例的安装卸载等等。需要说明的是,FedLCM并不是KubeFATE或其他部署方案的替代者,而是基于这些面向单方的方案,来完成在多个参与方部署的流程。

同时,FedLCM项目也为用户提供了一个站点管理平台 – Site Portal ,这是一个图形化的联邦学习任务管理服务,Site Portal的用户通过简单的操作就可以发起或加入一个联邦学习任务,并提供了包括项目、数据、模型等等的联邦学习要素的管理功能(在FedLCM的v0.1.0版本中,Site Portal服务需与FATE v1.6.1一起使用)。

B.FedLCM的核心概念

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

上图是Lifecycle Manager服务的核心素和它们之间的关联关系,具体来说,它包括以下几个核心概念:

1.      基础设施(Infrastructure):底层的基础设施资源是一切生命周期管理的基础,例如 Kubernetes集群、单机/VM 或其他设备等,目前FedLCM支持的基础设施是Kubernetes,FATE系统会以容器的形式运行在用户配置的Kubernetes基础设施之上。

2.      服务端点(Endpoint) :在基础设施上运行的,面向该基础设施的部署管理服务,Lifecycle Manager可以对其进行安装卸载等管理,并基于它来完成在对应的基础设施上的FATE系统的安装管理。目前FedLCM支持的服务端点种类即是K8s模式下的KubeFATE服务。

3.      联邦(Federation) :即一个可以由多个联邦学习参与者加入的联邦学习网络。是Lifecycle Manager架构中用户使用的最顶层的实体。

4.      联邦学习参与方(Participant) :即联邦内的一个参与方。它可以是一个FATE Exchange,或者是一个 FATE系统(也被称为FATE Cluster)。在一个联邦下允许创建一个Exchange和多个Cluster,也可以引入外部通过其他方式安装的Exchange 和 Cluster,以便于与其他方互联。

Lifecycle Manager服务设计的初衷是尽量灵活,它可以支持部署与管理多个联邦、不同类型的基础设施、服务端点等,且联邦学习参与方可以部署在以上任何一个实例上。除了以上核心概念之外,还有其他的一些实体与服务扮演着重要的角色,例如: Chart服务管理着用于部署 FATE 参与方的Helm Chart,这是与KubeFATE配合时不可或缺的资源;事件(Event)服务记录相关实体的重要事件与信息;证书 (Certificate)服务在FATE部署中为一些需要TLS的服务颁发证书等等。这些服务与核心实体相关联,用于整个生命周期管理的工作流,一起组成Lifecycle Manager的主要功能。

除此之外,Lifecycle Manager还可以部署一些其他重要服务,包括可用于颁发证书的 CA 服务,以及前文所述的,可以与各个参与方的FATE 实例同时运行的站点管理服务Site Portal。该服务可以帮助管理各个站点信息与联邦学习任务,用户可通过网页界面来管理 FATE 任务、模型、数据等,加速联邦学习任务的工作流程。这几个服务的部署场景如下图示例所示。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如何使用FedLCM

A.部署FedLCM

FedLCM本身可以以容器的方式,通过docker-compose或者Kubernetes部署运行。具体部署步骤可以参考GitHub仓库中的README.md文档。

(地址是:https://github.com/FederatedAI/FedLCM/blob/main/README_zh.md)

B.使用Lifecycle Manager

成功部署 FedLCM 后,用户可以通过它的网页进行后续的所有操作。一个使用FedLCM的最基本流程大概有下面几步骤:

  • 配置 CA:FedLCM 服务可以使用一个证书颁发机构来向各组件签发证书。FedLCM集成了流行的开源CA服务StepCA, 在docker-compose 和 K8s 部署方案中都默认内置一个可以直接使用的 StepCA 服务,方便用户快速开始。如果有需要,用户也可以接入已经存在的外部StepCA服务。当然,FedLCM也支持不配置任何CA,此时,用户需要手动为需要部署的FATE组件等签发证书。

  • 添加基础设施:FedLCM服务计划支持多种基础设施, 比如VM或者Kubernetes 集群。目前用户可以通过提交一个kubeconfig文件将K8s 集群添加为基础设施,目前FedLCM也支持为基础设施设置自定义镜像仓库等配置。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 安装服务端点:  FedLCM目前支持部署的服务端点的类型是KubeFATE。用户可以一步步按照提示在Kubernetes基础设施上安装KubeFATE。同时FedLCM也支持在安装服务端点同时自动安装Ingress Controller服务。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 创建联邦: 用户只需要提供简单的信息就可以创建一个联邦。其中的“主域名”将会作为该联邦中各个服务的域名的基础。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 创建参与方:用户可以在当前联邦下创建Exchange和Cluster(即FATE-Flow和各个基础引擎组成的集群), 也支持将其他联邦下的Exchange或Cluster引入当前联邦,以便于FedLCM更新其他参与方的路由表信息。创建Exchange与Cluster的步骤相似, 用户只要按照步骤提示就可快速完成创建。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

完成以上流程后, 我们就拥有了一个联邦并管理着多个参与方。

  • 在联邦页面,我们可以看到整个联邦的详情,包括各个参与方的状态等:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 参与方Cluster详情: 在 Ingress 信息一栏可以看到多个服务的网络信息,其中 client 提供Jupyter notebook服务来创建 FATE job,fateboard提供监控FATE  job 的服务。通过修改 hosts 文件或者配置 DNS 服务器后可访问到相应服务。如果使用1.6.1版本的chart创建FATE cluster, 用户也可以使用Site Portal服务来创建FATE Job, 下一章节将简单介绍此服务。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在FedLCM的开源仓库中,有上述步骤的详细文档,请参阅如下文档:https://github.com/FederatedAI/FedLCM/blob/main/doc/Getting_Started_FATE_zh.md 。

C.使用Site Portal

  • 如果使用1.6.1版本的chart创建FATE cluster, 部署成功后在“公开服务“一栏会包含 Site Portal 服务, 即可跳转到当前参与方的站点管理系统。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 进入Site Portal后, 用户可以通过配置站点信息连接到FML Manager和 FATE-Flow服务。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 用户可上传数据到系统并创建一个项目, 并邀请同一联邦下的参与方加入项目。

(Site-1 邀请Site-2加入project)

  • Site Portal支持创建模型训练,预测和PSI任务。当参与方向项目中关联数据后, 就可以发起一个FATE训练任务。目前Site Portal支持Json模板模式及拖拽交互模式来构建FATE训练任务Pipeline并生成DSL。
  • 训练任务创建并完成后会生成最终模型。各个参与方可以用此模型进行之后的预测任务。

由于篇幅原因,以上只是Site Portal简单的功能介绍。关于Site Portal详尽使用说明请阅读FedLCM项目库的相关文档,包括:

1.整体使用指南:https://github.com/FederatedAI/FedLCM/blob/main/doc/Site_Portal_In_FedLCM_Configuration_Guide_zh.md

2.训练任务创建说明:https://github.com/FederatedAI/FedLCM/blob/main/doc/Site_Portal_Create_Job_Guide_zh.md

结语

至此我们就完成从部署FedLCM、部署FATE集群到发起FATE Job的一整套流程。FedLCM以图形化的方式帮助用户高效、安全地完成联邦学习中的各个步骤,也方便用户更好地管理联邦学习中的各个素。FedLCM开源项目的地址在: https://github.com/FederatedAI/FedLCM 或阅读原文查看 。

欢迎大家使用并向我们提出宝贵意见, 更欢迎参与贡献到FedLCM的开源项目中。

 

内容来源|公众号:VMware中国研发中心

本文内容整理自 博学谷狂野架构师

事务的具体定义

​ 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单,组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交,只要其中任一操作执行失败,都将导致整个事务的回滚。简单地说,事务提供一种“要么什么都不做,要么做全套(All or Nothing)”机制

file

数据库本地事务

说到数据库事务就不得不说,数据库事务中的四大特性,ACID

A:原子性(Atomicity)

​ 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

​ 就像你买东西要么交钱收货一起都执行,要么要是发不出货,就退钱。

C:一致性(Consistency)

​ 事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

I:隔离性(Isolation)

​ 指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

打个比方,你买东西这个事情,是不影响其他人的

D:持久性(Durability)

​ 指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

打个比方,你买东西的时候需要记录在账本上,即使老板忘记了那也有据可查。

file

简单而言,ACID是从不同维度描述事务的特性:

  • 原子性 —— 事务操作的整体性
  • 一致性 —— 事务操作下数据的正确性
  • 隔离性 —— 事务并发操作下数据的正确性
  • 持久性 —— 事务对数据修改的可靠性

一个支持事务(Transaction)的数据库,需要具有这4种特性,否则在事务过程当中无法保证数据的正确性,处理结果极可能达不到请求方的要求。

什么时候使用数据库事务

​ 在介绍完事务基本概念之后,什么时候该使用数据库事务? 简单而言,就是业务上有一组数据操作,需要如果其中有任何一个操作执行失败,整组操作全部不执行并恢复到未执行状态,要么全部成功,要么全部失败。

​ 在使用数据库事务时需要注意,尽可能短的保持事务,修改多个不同表的数据的冗长事务会严重妨碍系统中的所有其他用户,这很有可能导致一些性能问题。

什么是分布式事务

分布式产生背景与概念

​ 随着互联网快速发展,微服务,SOA等服务架构模式正在被大规模的使用,现在分布式系统一般由多个独立的子系统组成,多个子系统通过网络通信互相协作配合完成各个功能。

​ 有很多用例会跨多个子系统才能完成,比较典型的是电子商务网站的下单支付流程,至少会涉及交易系统和支付系统,而且这个过程中会涉及到事务的概念,即保证交易系统和支付系统的数据一致性,此处我们称这种跨系统的事务为分布式事务,具体一点而言,分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

举个互联网常用的交易业务为例:

file

​ 上图中包含了库存和订单两个独立的微服务,每个微服务维护了自己的数据库。在交易系统的业务逻辑中,一个商品在下单之前需要先调用库存服务,进行扣除库存,再调用订单服务,创建订单记录。

file

可以看到,如果多个数据库之间的数据更新没有保证事务,将会导致出现子系统数据不一致,业务出现问题。

分布式事务的难点

事务的原子性

事务的一致性

​ 当发生网络传输故障或者节点故障,节点间数据复制通道中断,在进行事务操作时需要保证数据一致性,保证事务的任何操作都不会使得数据违反数据库定义的约束、触发器等规则。

事务的隔离性

​ 事务隔离性的本质就是如何正确多个并发事务的处理的读写冲突和写写冲突,因为在分布式事务控制中,可能会出现提交不同步的现象,这个时候就有可能出现“部分已经提交”的事务。此时并发应用访问数据如果没有加以控制,有可能出现“脏读”问题。

本文由教研团队发布。

如果本文对您有帮助,欢迎和;如果您有任何建议也可或,您的支持是我坚持创作的动力。

转载请注明出处!

国内外的用户都在使用云原生技术来提高应用的开发效率和可管理性,不少用户运用开源Harbor制品仓库,管理敏捷软件供应链中云原生应用的镜像,包括镜像存储、镜像扫描和镜像签名等功能。

Harbor已经提供了一些高级的安全功能,例如,对镜像进行扫描,以发现潜在的安全问题。Harbor的镜像扫描功能本质上属于静态扫描,即通过Trivy,Clair,雅客云(Arksec)等漏洞扫描器(scanner),对镜像进行由事件触发或周期性的扫描。静态扫描可检测到镜像文件中潜在的威胁,但部分有风险的镜像仍有可能通过扫描器的检测,并被部署到Kubernetes集群中,从而引入了运行时的风险。

举个例子,Harbor对某个镜像进行了扫描,检测结果是该镜像达到一定的安全级别,允许它上线运行。过了一段时间,有个新的CVE漏洞被发现,恰好该镜像包含了这个漏洞,在漏洞修复前Harbor不再容许该镜像上线。但是对已经处于运行态的镜像来说,Harbor则无能为力。

鉴于Harbor重点在云原生应用的静态安全保护,面对日趋严重的“供应链攻击”的风险,用户需要提高另一方面的安全能力,即动态安全保护(运行时安全保护)。


为此,我们推出了全新的开源项目CNSI, 即云原生安全检测器(Cloud Native Security Inspector),项目代号: Narrows。在Harbor的基础上,Narrows增强了动态安全方面的能力,它允许用户对Kubernetes集群和其中的工作负载进行运行时的安全态势评估。镜像仓库中的镜像可以在被引入到Kubernetes的集群时被扫描,同时Kubernetes集群本身的配置和状态一并被扫描并生成安全报告。从而让管理员发现、标记集群中所存在的安全漏洞,并对有漏洞的工作负载进行隔离。

Narrows所带来的运行时动态安全扫描能力非常关键,它帮助管理员对Kubernetes集群和其上工作负载有更好的安全状态控制和感知,而不仅仅是只关注工作负载的生命周期。

Narrows提供的能力包括:

·      对运行时的漏洞动态检测和感知

·      发现Kubernetes集群的错误配置

·      在工作负载运行时,终止进行中的攻击

·      对扫描报告进行汇总、聚合和分析并提供开放的API接口

·      与Harbor无缝的集成。对于外部公共镜像仓库的镜像,可以自动同步到Harbor中,以生成安全数据。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Narrows与Harbor进行了集成,如上图。Narrows允许用户通过简单的界面来定义对Kubernetes集群中工作负载的安全期望,并根据用户指定的扫描器和扫描周期对工作负载进行扫描。对于不满足安全要求的工作负载进行隔离。

当前版本的Narrows支持三种扫描器,分别是:

1.Image scanner (镜像扫描器)

将Kubernetes集群中镜像的安全漏洞等级与用户期望的安全漏洞等级进行比较,可以对不满足安全预期的工作负载进行隔离。

2.Kubebench scanner (Kubebench扫描器)

使用kubebench对Kuberentes集群的配置进行扫描,发现不合理的配置项并提供修改建议。

3.Risk scanner (运行风险扫描器)

对于工作负载中所包含的软件包进行扫描,并提供对应的CVE详情。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们计划通过接入新的安全数据源和引入新的扫描器来增强Narrows的检测能力。与此同时,我们将进一步深入研究并扩展对安全漏洞和不安全负载的处理能力。在安全数据分析洞察部分,我们期望可以将多维度的安全数据进行综合汇总,按照不同的场景和用户的偏好进行安全风险排序、筛选和结果呈现。

Narrows已经由VMware公司开源,采用商业化友好的阿帕奇 2.0软件许可,方便用户作扩展和创新。在社区方面,雅客云(Arksec)在Narrows最新发布中贡献了排序功能,可结合容器运行时的扫描对安全漏洞进行优先级排序。雅客云也将持续参与Narrows项目,计划贡献多项安全能力。


Narrows已经开源,项目的Github地址是:

https://github.com/vmware-tanzu/cloud-native-security-inspector

欢迎广大用户参与到我们的开源项目中,并期待您的使用和反馈。如果您对Narrows开源项目感兴趣,希望与我们更密切地合作,或者希望进行测试和试用、提出建议或bug,请发邮件至 narrows @ vmware.com。

内容来源|公众号:VMware 中国研发中心

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

本文搭配同主题分享视频阅读更佳,《多数据源的数据治理实践》

如果你装好某款数据库产品,比如:分布式图数据库 NebulaGrpah,跃跃欲试的第一步是不是就让它干活搞数据呢?好的,现在问题来了,如何把相对原始的数据处理、建模并导入 NebulaGraph 呢?本文是一个端到端的示例演示,从多数据源聚合数据,清理、利用 dbt 转换成 NebulaGraph 建模的属性图点边记录,最后导入成图谱的全流程。

构建知识图谱

现在假设你是一个类似于 Netflix、爱奇艺之类的视频服务提供商,我们需要利用图数据库搭建一个 的知识图谱,来辅助、支撑视频推荐、问答和推荐理由等常见由图谱支撑的场景。由于时间的关系,这里先用我们熟悉的老朋友——图数据库 NebulaGraph 来搞定知识图谱。

一般来说,知识图谱需要的数据会有不同的数据来源,比如一些公开的 API、数仓中的不同数据库、静态文件。这时候,我们如果要构建知识图谱,需要以下 3 个步骤:

  1. 分析可能获取的数据;
  2. 选取关心的关联关系,图建模;
  3. 抽取关联关系,导入图数据库。

数据源

这里我们会用到两个数据源 OMDB 和 MovieLens。

OMDB 是一个开放的电影数据库,将用来模拟公司内部的业务数据。我们可以获得的信息有:

  • 电影
  • 电影的分类
  • 电影中的工作人员,包括:导演、动作指导、演员、后期制作等人员信息
  • 电影封面、宣传片等电影信息

MovieLens 是一个开放的数据集,用来模拟公司内部的用户数据。我们可以获得的信息有:

  • 用户
  • 电影
  • 用户对电影的评分交互

图建模

在之前的文章《基于图数据库的推荐系统》 里我们介绍了推荐系统的图数据库基本用法。在那篇文章中,内容过滤侧重关注 、、、 等关系,协同过滤则关注 的关系,以及推荐理由服务关注以上所有的关系。

总结起来,我们需要的边有:

  • watched(rate(double))
  • with_genre
  • directed_by
  • acted_by

结合已有信息,相对应地将顶点中可能需要被关注的信息作为属性,给出点 tag 的初始规划:

  • user(user_id)
  • movie(name)
  • person(name, birthdate)
  • genre(name)

schema_0

表数据到知识图谱的映射

有了目标的图谱结构定义,我们来看看手上的数据如何映射到它。

OMDB 数据

首先是 OMDB 数据,它由很多表组成,比如 这张表,存储了所有的电影、以及它们在不同语言下的名字:

movie_id name language_iso_639_1 official_translation 1 Cowboy Bebop de 1 1 Cowboy Bebop en 1 2 Ariel – Abgebrannt in Helsinki de 0 3 Shadows in Paradise en 0 3 Im Schatten des Paradieses de 0 3 Schatten im Paradies de 1

而 表格中保有所有电影相关的工作人员:

movie_id person_id job_id role position 11 1 21 1 11 1 13 1 11 2 15 Luke Skywalker 1 11 3 15 Han Solo 3 11 4 15 Leia Organa 2

但是这里的每一个人的姓名等信息、以及他/她在电影中任职的职位,则分别在表 和 中:

这里讲解下 表,1 代表编剧、2 代表制作人。有意思的是,和上表的电影 id 与 name 字段一样,job_id 到 name 也是一对多的关系,因为 OMDB 中的数据都是多语言的。

job_id name language_iso_639_1 1 Autoren de 1 Writing Department en 1 Departamento de redacción es 1 Département écriture fr 1 Scenariusz pl 2 Produzenten de 2 Production Department en

下面这张表是 :

id name birthday deathday gender 1 George Lucas 1944-05-14 N 0 2 Mark Hamill 1951-09-25 N 0 3 Harrison Ford 1942-07-13 N 0 4 Carrie Fisher 1956-10-21 2016-12-27 1 5 Peter Cushing 1913-05-26 1994-08-11 0 6 Anthony Daniels 1946-02-21 N 0

这是在数据来源是表结构、RDBMS 中,是一个很典型的情况,所以对于 这个关系,就涉及了 ,,, 四个表格:

  • directed_by
    • 起点 person_id 在 之中
    • 终点 movie_id 在 之中
      • 条件是 job_id 为 之中的 “director”
  • movie
    • person_id 在 之中
    • 名字来自 中按 id 查找,language 为 “en”
  • person
    • movie_id 在 之中
    • name、birthday 在 之中

所有 OMDB 中我们关心的表的关联如图:

modeling_omdb

MovieLens 数据集

上面我们讲述了单数据源的场景,只有单一数据源、数据表或者数仓的数据。但在真实场景中,我们还需要从其他源头收取数据,并聚合起来。在本例中,我们还需要从 MovieLens 的数据集中抽取需要的知识。

这里,涉及到 MovieLens 数据集,我们利用的只有:,这一条关系。

数据:

movieId title genres 1 Toy Story (1995) Adventure 2 Jumanji (1995) Adventure 3 Grumpier Old Men (1995) Comedy 4 Waiting to Exhale (1995) Comedy

数据:

userId movieId rating timestamp 1 1 4 1 3 4 1 6 4

从两个表的数据预览似乎可以得出:

  • watched
    • 起点来自于 中的 userId
    • 终点来自于 中的 movieId
    • 评分来自于 中的 rating
  • user
    • 来自于 中的 userId

然而,细心的你们一定发现 MovieLens 数据集中的 movieId 和来自于 OMDB 中的电影 id 完全是不同的两套体系。如果我们需要让它们关联起来,需要将 MovieLens 里的 movieId 转换成为 OMDB 中的电影 id,而它们之间的关联条件则是电影的标题。

但是,通观察我们知道:

  1. OMDB 电影中标题是多语言的
  2. MovieLens 中的标题结尾带有这样的年份信息

所以我们最终的结论为

  • watched
    • 起点来自于 中的 userId
    • 终点来自于 中的 movieId,终点要从 中的 title ,在 OMDB 之中查找,得到 OMDB 的 movie_id。查找条件为去掉年份,从 OMDB 的英文标题中进行匹配
    • 评分来自于 中的 rating
  • user
    • 来自于 中的 userId

现在,这个表格之间的关系如下

modeling_omdb_movielens

映射数据到图谱(属性图)

到这里小结下,我们需要对多个数据源中的不同表格(或者表格形式的 CSV 文件)进行聚合,这样的对应关系如图所示:蓝色虚线表示图中顶点的数据信息来源,粉色虚线表示边信息的来源。

schema_mapping_to_graph

此外,我们还要对不同表中个体的 id 进行格式化,比如 user_id,是自增的数字,我们要转换成全局唯一的 vertex_id。比较方便的方法是在现有 id 的基础上增加字符串前缀,比如 。

最终,以 关系为例,我们可以处理得到这样的表结构数据:

user_id rating title omdb_movie_id u_1 5 Seven (a.k.a. Se7en) 807 u_1 5 Star Wars: Episode IV – A New Hope 11 u_1 5 Star Wars: Episode IV – A New Hope 10 u_1 4 Mask, The 832 u_1 3 Mrs. Doubtfire 832

其中每一行记录中存在三个图上的结构信息:

  • user 顶点 id
  • movie 顶点 id
  • watched 边的 rating 值

数据工具

好的,我们现在已经完成了数据的分析与建模设计,在进入”抽取关联关系,导入图数据库“环节之前,先介绍一下我们要用到的工具。

”抽取关联关系“可以简单认为是 ETL 中的 Extract 和 Transform。本质上就是工程上执行数据映射与转换的工作,市面上有很多不同风格的工具、开源项目可以做 ETL 这件事。这里我们用到我个人比较喜欢的工具:dbt。

数据转换利器 dbt

dbt 是一个开源的数据转换工具,它有非常成熟的社区和生态,可以在大多数主流数仓之中进行高效、可控、高质量的数据转换工作。无论是临时的转换工作(ad-hoc),还是在给定的定时 pipeline 中进行复杂编排,dbt 都可以很好胜任。它的一大特色就是使用 SQL LIKE 语言去描述数据转换的规则。此外,它还基于 GitOps 可以非常优雅地多人协作、维护超大规模数据团队里复杂的数据处理作业。而 dbt 内置的数据测试能力可以很好地控制数据质量,可复现、控制数据问题。

dbt 不仅有许多集成的子项目,还能和像是 Meltano、Airflow、Amundsen、Superset 之类的优秀开源项目有机地结合,形成一整套现代的数据基础设施体系。对具体实践感兴趣的同学可以阅读文末「参考资料中」的数据治理实践。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

简单来说,dbt 是一个 Python 写的命令行工具。针对不同的项目,我们可以用 dbt 创建特定格式的项目文件夹,它会自带一个 配置文件。我们要在配置文件里指定数据转换的来源信息在哪里,目标在哪里(处理之后的数据存储的地方,可能是 PostgreSQL、BigQuery、Spark 等)。在数据源中,我们用 yaml 文件和 文件一起描述了”从哪里取哪些数据,如何做变换,输出什么“的信息。

starter-project-dbt-cli

这个截图就是 dbt 官方文档中的示例项目中的文件和配置,可以看到 里的信息就是最核心的数据转换 transform 的规则,而所有的其他数据都是和这个数据转换相关的数据,这些 dbt 项目文件非常适合用 git 来进行维护,进行现代、自动化的 DataOps。

NebulaGraph 数据导入

经过 dbt 对数据进行处理之后,我们可以得到直接映射到不同类型的顶点、边、及其属性的表结构的中间数据,它们可以是 CSV 的文件形式,也可以是数仓中的表,甚至可能是 Spark 中的 DataFrame。而将它们导入 NebulaGraph 有不同的选择,可以选数据导入工具 NebulaGraph Exchange、NebulaGraph Importer、NebulaGraph Spark Connector 的任意一款。

在这里,用最简单的 NebulaGraph Importer 作为例子。

NebulaGraph Importer 是一个用 Golang 写的开源数据工具。它可以编译成一个单文件的二进制,通过预配置的 yaml 格式的文件,读取指定 CSV 文件映射到 NebulaGraph 中点、边关系数据。

实操

现在,我们来实操下如何利用 dbt + NebulaGraph Importer 进行多数据源聚合、转换,再导入 NebulaGraph 的过程。整个项目的代码已经开源,仓库在 https://github.com/wey-gu/movie-recommendation-dataset 上,欢迎大家参考、共建。

整个实操过程如下:

  • 将源数据简单清洗、导入数仓 PostgreSQL(EL)
  • 用 dbt 对数据进行转换 Transform、导出为 CSV 文件
  • 用 NebulaGraph Importer 将 CSV 导入 NebulaGraph(L)

ETL_dbt_nebulagraph_importer

准备 dbt 环境

dbt 是一个 Python 项目,我们在一个虚拟的 Python 3 环境里安装好 dbt 和 dbt-postgres。


创建一个 dbt 项目,并进入到空的项目里:


看看里边的文件吧:


最后,咱们拉一个容器里的 Postgres 当做我们这个项目的数仓。如果你已经有各种其他数仓,就不需要这一步了,不过要把项目中的配置文件作相应的修改,并安装相应的 dbt 插件。


数据下载与预处理

我们把数据放到项目的 下吧。


注意,假设 在 之下:


我们把 OMDB 数据下载之后,再解压:


然后是 MovieLens 数据集的下载、解压:


在导入数仓进行转换 Transform 之前我们做一些数据的预处理,把它们放到 之下。


有了 seeds 下边的文件之后,可以用一个命令把他们导入到数仓里:


执行过程因数仓而异,用本地的 Postgres 可能要等一会儿才能完成,执行结果大概是这样的:


撰写 Transform model

我们创建 model 如下:


这时候 models 中的文件结构大概是这样的:


这个 model 下边目前只有一个规则,就是负责处理用户观看电影这条边上数据的 SQL 语句。

我们希望输出三列,所以 中的内容是:


注意,这里的 的表达是对数据验证、测试的约束。有了它,我可以用 dbt 轻松地对数据质量进行测试、验收,比如:我们要求这里的三个字段都是 。

然后,我们来写 SQL 吧,:


而这个 SQL 做的事情就是绿色圆圈标注的部分:

  • 从 中选 user id、movie id、rating、movie title(去掉年份),存成 的中间表格
    • movie title 从 中 ,通过 相同的匹配条件取得
  • 从 中选 user id(增加前缀 )、rating、title、OMDB_movie_id
    • OMDB_movie_id 从 中 ,通过相似的电影姓名匹配 OMDB 电影中英文标题取得
    • 最终的字段作为输出

transform_select_joins_user_watched_movies

当然,我们可以在 Postgres 的连接器中通过增加 LIMIT 快速调试自己的 SQL 语句。

现在我们来通过 dbt 执行、测试刚刚的规则:


之后,我们应该就可以在 Postgres(数仓)中看到我们转换之后的一个表了。

类似的,如法炮制所有其他部分的 Transform 规则,我们就获得了这么多 model 了:


再对他们分别执行 transform:


导出数据为 CSV

实际上,NebulaGraph Exchange 本身就支持把很多数据源(Postgres,ClickHouse,MySQL,Hive 等等)导入 NebulaGraph。只是在这个例子中,我们处理的数据量对于 NebulaGraph 来说非常非常小(只有百万级别的边而已),所以使用最轻量级的 NebulaGraph Importer 就足够了。而 NebulaGraph Importer 能消费的数据只有 CSV 文件,所以我们把刚才的表都输出为文件。

首先,我们进入 Postgres 的 Console,执行 命令


再把 Postgres 容器里的文件导入到 这个文件夹里:


导入 NebulaGraph

创建 NebulaGraph 集群

我们可以用 Nebula Up 一键拉起一个测试的 NebulaGraph 单机集群,导入所需数据:


创建 Schema

首先,我们创建一个叫做 的图空间。针对前面的建模,创建点边类型的结构 Schema:

先进入 NebulaGraph 的 Console:


再执行如下 DDL(Data Definiation Language):


创建 NebulaGraph Importer 配置文件

这个文件是一个描述 CSV 文件和集群中点边数据对应关系的 YAML 文件。详细的格式可以参考文档:https://docs.nebula-graph.com.cn/master/nebula-importer/use-importer/,或者视频教程:https://www.bilibili.com/video/BV1ny4y1u7i4。

最终的配置文件我已经为大家写好了,在 https://github.com/wey-gu/movie-recommendation-dataset/blob/main/nebula-importer.yaml 可以下载得到。

这里,我们就直接下载我写好了的配置文件。注意,这个文件不应该是 dbt 项目文件的一部分,所以我们退出目录,向上一层,把它放到 外边:


开始导入

这一步,我们用容器化的 NebulaGraph Importer,避免了安装的步骤:


很快,所有的数据就导入到 NebulaGraph 之中了。现在,我们可以通过 NebulaGraph Console,执行一些查询看看结果:

进入 Console:


进入图空间、执行 :


结果:


通过 NebulaGraph Studio,我们也可以在可视化界面探索这个图谱。比如:在其中执行这个查询,看一下给用户 推荐电影 的理由可能是什么?


它的结果是:曾经喜欢的星战电影的大部分演职人员都也参与了这部同样是“奥斯卡获奖”且“经典”的电影。

reasoning_movie

总结

当我们打算把海量数据利用图数据库的能力进行知识转化、洞察分析的时候,往往第一步就是要做多数据源到图数据的转换、处理、建模。对于无从下手的新手们来说,一个可行的思路是从所有的相关信息出发,去设想最关注的关联关系,把边写出来,然后再罗列可以取得的点、以及需要的点、边上的属性。确定了初始的建模之后,就可以利用 ETL 工具把原始的数据清洗、ETL 成点、边类型的表结构,最后,利用导入工具导入 NebulaGraph。

借助于 dbt,我们可以版本控制、测试、迭代建模与数据转换,一点点进化、丰富构建的知识图谱。

参考资料

  • 数据血缘治理:https://discuss.nebula-graph.com.cn/t/topic/11729
  • dbt 上手文档:https://docs.getdbt.com/docs/get-started/getting-started-dbt-core
  • 如何选择 NebulaGraph 数据导入工具:www.siwei.io/sketches/nebula-data-import-options
  • Postgres 文档:https://www.postgresql.org/docs/current/sql-copy.html
  • 基于图数据库的推荐系统:https://discuss.nebula-graph.com.cn/t/topic/11491

谢谢你读完本文 (///▽///)

要来近距离快速体验一把图数据库吗?现在可以用用 NebulaGraph Cloud 来搭建自己的图数据系统哟,快来节省大量的部署安装时间来搞定业务吧~ NebulaGraph 阿里云计算巢现 30 天免费使用中,链接来用用图数据库吧~

想看源码的小伙伴可以前往 GitHub 阅读、使用、(^з^)-☆ star 它 -> GitHub;和其他的 NebulaGraph 用户一起交流图数据库技术和应用技能,留下「你的名片」一起玩耍呢~    

> 温馨提示:本文需要结合上一篇 gRPC 文章一起食用,否则可能看不懂。

前面一篇文章松哥和大家聊了 gRPC 的基本用法,今天我们再来稍微深入一点点,来看下 gRPC 中四种不同的通信模式。

gRPC 中四种不同的通信模式分别是:

  1. 一 RPC
  2. 服务端流 RPC
  3. 客户端流 RPC
  4. 双向流 RPC

接下来松哥就通过四个完整的案例,来分别和向伙伴们演示这四种不同的通信模式。

1. 准备工作

关于 gRPC 的基础知识我们就不啰嗦了,咱们直接来看我今天的 proto 文件,如下:

这次我新建了一个名为 book.proto 的文件,这里主要定义了一些图书相关的方法,如下:


这个文件中,有一些内容我们在上篇文章中都讲过了,讲过的我就不再重复了,我说一些上篇文章没有涉及到的东西:

  1. 由于我们在这个文件中,引用了 Google 提供的 StringValue(),所以这个文件上面我们首先用 import 导入相关的文件,导入之后,才可以使用。
  2. 在方法参数和返回值中出现的 stream,就表示这个方法的参数或者返回值是流的形式(其实就是数据可以多次传输)。
  3. message 中出现了一个上篇文章没有的关键字 repeated,这个表示这个字段可以重复,可以简单理解为这就是我们 Java 中的数组。

好了,和上篇文章相比,本文主要就是这几个地方不一样。

proto 文件写好之后,按照上篇文章介绍的方法进行编译,生成对应的代码,这里就不再重复了。

2. 一 RPC

一 RPC 是一种比较简单的 RPC 模式,其实说白了我们上篇文章和大家介绍的就是一种一 RPC,也就是客户端发起一个请求,服务端给出一个响应,然后请求结束。

上面我们定义的五个方法中,addBook 和 getBook 都算是一种一 RPC。

2.1 addBook

先来看 addBook 方法,这个方法的逻辑很简单,我们提前在服务端准备一个 Map 用来保存 Book,addBook 调用的时候,就把 book 对象存入到 Map 中,并且将 book 的 ID 返回,大家就这样一件事,来看看服务端的代码:


看过上篇文章的小伙伴,我觉得这段代码应该很好理解。

客户端调用方式如下:


这里我使用了 CountDownLatch 来实现线程等待,等服务端给出响应之后,客户端再结束。这里在回调的 onNext 方法中,我们就可以拿到服务端的返回值。

2.2 getBook

getBook 跟上面的 addBook 类似,先来看服务端代码,如下:


这个 getBook 就是根据客户端传来的 id,从 Map 中查询到一个 Book 并返回。

客户端调用代码如下:


小伙伴们大概也能看出来,addBook 和 getBook 基本上操作套路是一模一样的。

3. 服务端流 RPC

前面的一 RPC,客户端发起一个请求,服务端给出一个响应,请求就结束了。服务端流则是客户端发起一个请求,服务端给一个响应序列,这个响应序列组成一个流。

上面我们给出的 searchBook 就是这样一个例子,searchBook 是传递图书的 tags 参数,然后在服务端查询哪些书的 tags 满足条件,将满足条件的书全部都返回去。

我们来看下服务端的代码:


小伙伴们看下,这段 Java 代码应该很好理解:

  1. 首先从 request 中提取客户端传来的 tags 参数。
  2. 遍历 bookMap,查看每一本书的 tags 是否等于客户端传来的 tags,如果相等,说明添加匹配,则通过 将这本书写回到客户端。
  3. 等所有操作都完成后,执行 ,表示服务端的响应序列结束了,这样客户端也就知道请求结束了。

我们来看看客户端的代码,如下:


客户端的代码好理解,搜索的关键字是 ,每当服务端返回一次数据的时候,客户端回调的 onNext 方法就会被触发一次,当服务端之行了 之后,客户端的 onCompleted 方法也会被触发。

这个就是服务端流,客户端发起一个请求,服务端通过 onNext 可以多次写回数据。

4. 客户端流 RPC

客户端流则是客户端发起多个请求,服务端只给出一个响应。

上面的 updateBooks 就是一个客户端流的案例,客户端想要修改图书,可以发起多个请求修改多本书,服务端则收集多次修改的结果,将之汇总然后一次性返回给客户端。

我们先来看看服务端的代码:


客户端每发送一本书来,就会触发服务端的 onNext 方法,然后我们在这方法中进行图书的更新操作,并记录更新结果。最后,我们在 onCompleted 方法中,将更新结果汇总返回给客户端,基本上就是这样一个流程。

我们再来看看客户端的代码:


在客户端这块,updateBooks 方法会返回一个 StreamObserver<book> 对象,调用该对象的 onNext 方法就是给服务端传递数据了,可以传递多个数据,调用该对象的 onCompleted 方法就是告诉服务端数据传递结束了,此时也会触发服务端的 onCompleted 方法,服务端的 onCompleted 方法执行之后,进而触发了客户端的 onCompleted 方法。

5. 双向流 RPC

双向流其实就是 3、4 小节的合体。即客户端多次发送数据,服务端也多次响应数据。

我们先来看下服务端的代码:


这段代码没有实际意义,单纯为了给小伙伴们演示双向流,我的操作逻辑是客户端传递多个 ID 到服务端,然后服务端根据这些 ID 构建对应的 Book 对象,然后三个三个一组,再返回给客户端。客户端每次发送一个请求,都会触发服务端的 onNext 方法,我们在这个方法中对请求分组返回。最后如果还有剩余的请求,我们在 onCompleted() 方法中返回。

再来看看客户端的代码:


这个客户端的代码跟第四小节一模一样,不再赘述了。

好啦,这就是松哥和小伙伴们介绍的 gRPC 的四种不同的通信模式,文章中只给出了一些关键代码,如果小伙伴们没看明白,建议结合上篇文章一起阅读就懂啦~</bookset></stringvalue></stringvalue></bookset></stringvalue></book></string,></book></stringvalue></book></book></stringvalue></book></string,></book></string></book></string,></book></book></string,></stringvalue></stringvalue></string,>

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

内容简介

随着数字化不断发展,各行各业数据呈现海量增长的趋势。存算分离将存储系统和计算框架拆分为独立的模块,Alluxio作为如今主流云数据编排软件之一,为计算型应用(如 Apache Spark、Presto)和存储系统(如 Amazon S3、Alibaba OSS)的数据访问构建了桥梁。

本文使用亚马逊云、阿里云服务商产品,对Presto、Hive等计算框架与不同UFS直连时的关键性能指标进行测评,同时给出集成Alluxio组件后的性能评估,得出以下结论:

  • Alluxio 可减少任务运行时间(低带宽情况下甚至可以减少一个数量级)和 CPU时间;这表明 Alluxio 一定程度上可以节省带宽并减轻服务器运算压力。
  • Alluxio 可更好地兼容众多底层存储系统,这表明在不损失性能的前提下,选择价格更为低廉的对象存储系统(如Alibaba OSS, Amazon S3)。

简而言之,集成数据驱动软件 Alluxio 既能提升性能,又能降低运营成本。

实验设计

本实验采用 TPC-DS 生成的 1GB 数据集,选择19条SQL作为该实验工作负载。[1]

Type Queries Interactive Q19, Q42, Q52, Q55, Q63,Q65, Q68, Q73, Q98 Reporting Q3, Q7, Q27, Q43, Q53, Q89 Deep Analytics Q34, Q46, Q79, SS_MAX

我们将原始数据存到底层存储系统中,使用Hive管理原始数据和数据,将Presto作为计算应用,形成 Presto → Hive → (Alluxio →) HDFS/OSS/S3 的连接模式,并进行Presto直接读UFS和Presto通过Alluxio缓存读UFS两种对比测试。我们采用挂钟时间(WallTime,执行查询花费的总时间)和CPU时间(ProcessCpuTime,处理查询所花费的总CPU时间)两组测量指标进行对比测试。

实验结果与意义

实验结果分析

通过TPC-DS测试的对比后,可得出以下几点结论:

(1)Alluxio 可减少挂钟时间,在低带宽下尤为明显。

√ 图1-1是在AWS上,使用HDFS作为存储系统,统计挂钟时间均值(AWS实例带宽最高可达10G/s,性能小幅度提升):

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图1-1

  • 图1-2是在阿里云上,使用HDFS作为存储系统,统计挂钟时间均值(选择阿里云按量付费最高带宽200M/s):
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图1-2

  • 图1-3是在阿里云上,使用HDFS作为存储系统,统计挂钟时间均值(低带宽模式,带宽15M/s),可以看到性能提升一个数量级。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图1-3

(2)Alluxio 可节省带宽。由图1-2和图1-3可知,若想在无Alluxio的情况下达到有Alluxio的效果,需要设法进一步提升公网带宽。

(3)Alluxio 一定程度上可减轻服务器运算压力,CPU时间较短。

图2-1是在阿里云上使用HDFS作为存储系统,统计CPU时间。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图2-1

图2-2是在AWS上使用S3作为存储系统,统计CPU时间。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图2-2

(4)Alluxio 为计算框架和存储系统的数据访问搭建桥梁,大大降低运行环境配置难度。目前 Presto 对 S3 兼容性较好,但对 OSS 和 COS 兼容性较差,目前尚无Presto直接访问OSS数据的方案。但用Alluxio则无需考虑计算框架和底层存储系统的兼容性问题,因为Presto对Alluxio、Alluxio对OSS兼容性很好,配置环境很容易。

(5)由于无需考虑计算框架与底层存储系统兼容性,则可使用价格更为低廉的对象存储系统,其带宽成本与维护成本均比 Hadoop 低。并且由图3-1和图3-2得知Alluxio缓存读情况下性能差别并不明显,但对象存储系统价格更为低廉,因此对象存储可作为存储系统更好的选择。

图3-1为使用AWS服务器,分别对 HDFS 和 S3 进行测试,统计挂钟时间。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图3-1

图3-2为使用阿里云服务器,分别对 HDFS 和 OSS 进行测试,统计挂钟时间。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

图3-2

对象存储与HDFS存储成本对比

由于云服务产品种类繁杂、使用相同产品不同的应用场景下开销差异较大。以本实验为例,云服务主要开销由存储、数据传输和云服务器三个部分构成,故我们仅对本实验使用云服务产品及其他常用云服务产品进行上述指标的定量分析(忽略诸如数据请求、对象清单等极低成本服务的指标),扩展服务及其详细价格详情请参考云服务产品价格页面。

亚马逊云

亚马逊服务器使用 S3 和 HDFS 作为存储系统时(HDFS 使用 EBS 存储,因此以美国东部俄亥俄2023年1月6日 S3 Standard 和 EBS 为例),价格对比如下(数据来源:Amazon S3 价格、Amazon EC2 实例价格、Amazon EBS 定价 ):

(1)存储

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

本实验采用S3 Standard 、通用型SSD (gp2) 和一张普通快照,S3 每 GB 存储价格仅为 gp2 的 1/7~1/6。即使数据量增大,使得运行环境占用存储忽略不计,在不考虑快照的情况下,S3 Standard 数据存储价格仅为 gp2 的1/4~1/3。

(2)数据传输

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

AWS两者公网流出流量价格一致,公网流入流量均免费。

(3)服务器成本

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

服务器成本请参考 Amazon EC2 实例价格,S3 并无此项成本,而 EC2 成本很高,以本实验存储系统用到的实例为例(美国东部俄亥俄2023年1月6日 r5a.large 价格)。

阿里云

以2023年1月12日华北1(青岛)区域的 OSS 标准型存储和块存储 (EBS) 为例(数据来源:对象存储OSS 定价详情、块存储定价详情)。

(1)存储

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

本实验采用 OSS 标准存储(本地冗余)、ESSD 云盘 PL0 和一个普通快照,可见在 Alluxio 缓存读性能相近情况下,OSS 每 GB 存储价格仅为 EBS 的 1/6~1/5。

(2)数据传输

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

本实验采用按量付费带宽。可见 OSS 带宽成本比 HDFS 带宽成本要低一些。倘若OSS开启CDN加速,理论上可进一步提升带宽速度并降低带宽成本。

(3)服务器成本

服务器成本请参考 云服务器 ECS,OSS 并无此项成本,而 ECS 成本很高,以本实验存储系统用到的实例为例(华北1青岛2023年1月12日 ecs.r6.large 价格)。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

总结

综合亚马逊云、阿里云的存储、数据传输和服务器成本,使用对象存储系统的开销要比HDFS低很多,而使用 Alluxio 可十分方便地接入各种存储系统,这无疑意味着可大大降低企业运营成本。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

想要了解更多关于Alluxio的干货文章、热门活动、专家分享,可进入【Alluxio智库】:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

参考

  1. ^我们选择和《SQL-on-Hadoop: Full Circle Back to Shared-Nothing Database Architectures》(Proceedings of the VLDB Endowment, Vol. 7, No. 12)相同的20条SQL作为该实验工作负载。Q59 由于过于复杂,运行时间过长,内存消耗过大,测试难度较大,故该实验仅对其他19个SQL进行测试。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

新春愉快,开工大吉!

在过去的一年里,为了响应社区的需求,NGINX 不仅全新推出了开源的 NGINX 企阅版以及 NGINX Management Suite 管理工具,还累计翻译了超过100篇英文博客文章以及电子书供大家免费学习参考。

2023年,NGINX将开启更多开源项目,积极参与开源生态的建设,并持续改进我们的产品功能和服务质量。

新年伊始,我们希望通过一个简短的调查问卷,了解NGINX中文用户的使用现状及反馈诉求,以便能够在新的一年更好地规划产品路线,并为社区提供需要的相关资源。

本次问卷调查仅需要5分钟即可完成,完整填写问卷就有机会获得精美礼品!

本次活动的奖品包括:

– 特等奖:Apple AirPods无线耳机3个

– 一等奖:新秀丽双肩包5个

– 二等奖:NGINX定制T恤盲盒50件

– 三等奖:NGINX定制手机支架 100个

感谢您一直以来对于 NGINX 的支持和关注,您的宝贵意见和建议将是我们前进的动力,非常期待听到您的反馈和诉求。

这里 https://www.wenjuan.com/s/UZBZJvxJBr0/?group=media-oschina,立即填写问卷!

 

青藤云安全是一家主机安全独角兽公司,看名字就知道当前很大一块方向专注云原生应用安全,目前主营的是主机万相/容器蜂巢产品,行业领先,累计支持 800万 Agent。当前公司基于 NebulaGraph 结合图技术开发的下一代实时入侵检测系统已经初步投入市场,参与了 2022 护网行动,取得了不错的反响。

本文将简单介绍基于图的入侵检测系统,抛砖引玉,期望能有更多优秀人才参与挖掘图与安全的结合应用。

入侵检测的现状与挑战

主流入侵检测系统

入侵检测一直是安全研究的一大方向,青藤的万相和蜂巢两套产品分别为基于主机和容器的主机入侵检测产品,它们的原理都类似,如下图。

入侵检测系统架构图

Agent 埋在主机/容器侧,接收服务端下发的规则结合采集的原始事件(进程/网络连接/文件读写等),通过安全专家编写规则,比如:进程文件 MD5/文件 MD5/执行命令行/机器学习等特征,命中当做告警报出来,相关告警上报到服务端;另外全量的原始事件也上报给服务端日志收集系统,入库保存到 SIEM 系统。

这套系统一旦告警上报到服务端,安全人员会拿当前告警相关信息到 SIEM 中查询告警发生时刻前后相关的事件,必要时登录相关机器查看相关信息,综合判断当前攻击告警是否有效并做相关处置。

这套系统是当前入侵检测的主流架构,但是也存在诸多问题:

  1. 基于单事件+规则做单点检测,可能造成大量误报(规则太松)或漏报(规则太严)
  2. 同一次攻击触发的告警可能过多,安全分析人员分析溯源工作量巨大
  3. 同一次告警相关原始事件需要借助 SIEM 人工分析,缺乏可视化手段

图与安全研究方向

其实,可以看到这里的几个问题点本质上都是独立去看待每个告警和事件,实际上一次攻击相关的告警/事件应该是彼此关联的,这里很自然想到用图去把这些原始事件/告警关联起来整体分析。事实上,这也是当前安全研究的一个热门方向——溯源图,借助溯源图我们做如下多方面的安全分析和检测:

1.图检测

传统安全解决的类似 IOC 检测,也就是单点判断,针对进程/网络连接/文件等实体判断是不是安全的;实际攻击面临的问题,可能各个点都检测不出来,但实际行为是危险的——1 个规则写不全,就算规则能写出来,比如命中某个命令行,但是触发告警很多,最终也无法应用。也就是要综合判断各种组合关系,这是图擅长的事情,也就是安全中图检测的问题——把所有相关的事件放在一张图中来综合判断分析是否为有效攻击。

图检测研究很早,但是面临计算量和算法的双重挑战,目前行业应用很少,基本上组合判断都还是序列检测方式。问题是序列规则能写多少确定规则,规则太多也有问题,无法应用;刚才提到确定规则,无法很好模糊匹配,也就是挖掘,安全中规则太确定就可以被绕过,黑客很聪明且借助自动化攻击更容易绕过这些规则。

2.图关联和溯源

刚才提到告警,也就是当前所有安全产品面临的另一个问题——要不是规则命中不了,要不就是规则命中太多,我们叫告警淹没,安全运营处理能力有限,可能一天 100 个告警还好,如果一天甚至一小时 10000 条告警就没法处理了,那和没告警没差别。

这其实是一个安全中关联分类和溯源的问题:

  1. 一次攻击会产生很多告警,比如:暴力激活成功教程登录,用了恶意文件,执行了恶意命令等等,关联分类把一次攻击中相关的告警关联在一起,这是图擅长的事情。这些告警关联在一起,还可以综合评判也就是多个告警联合判断当前攻击是否有效;
  2. 每个告警只会告诉你当前你是进程、文件、网络有问题,那这个问题是如何发生的,黑客是怎么进来的,文件是从哪里下载的,先干了什么后干了什么。安全产品需要帮助客户完成这个分析过程,目前行业是借助 SIEM/THP/SOC 等安全产品,所有原始事件都上传保存,找安全专家,从告警开始查原始事件日志,看告警前发生了什么,哪些有关系可能导致攻击,这个过程短则几分钟,长甚至数个小时。安全是个对抗过程,早就是优——越早发现越早对抗,封禁或隔离,否则就算发现也为时过晚。可以把相关的原始事件实体(进程/网络等)入图,借助图可以可视化探索和溯源整个攻击过程,这就是图溯源的过程,学术叫因果图、溯源图。

3.图知识图谱和预测

我们知道当前安全从根本上讲还是基于规则或者说先验知识,每种漏洞/木马/攻击工具/攻击过程/攻击组织都有它的特征,前几种规则还比较好描述,攻击过程、攻击组织等就很难完整描述了。

目前的主流做法是基于安全框架构建知识库,当前主流有 Kill Chain/ATT&CK 等框架,这是美国国防部主导的网络攻击战争相关两家公司提出的安全分析框架,相当于划分了攻击的战术和具体攻击技术的映射,这个具体如何实施比较难。安全学术界,比如:伊利诺伊大学/普渡大学近两年都在研究类似问题,也就是安全知识库(安全知识图谱)的构建。有了这个完善的知识库,就可以完成安全的终极设想,比如:我知道你的攻击过程/攻击组织,是不是就可以在攻击真正开始前,好比你打仗刚拿起枪冲到阵地上,判断你是要朝我开枪,预判直接击毙。

国内外现状

目前基于图的入侵检测系统,真正率先投入到实战中的是美国的安全明星公司——Crowd Strike,它完全基于图构建安全系统,现在相当于做了图检测和图关联溯源这两块的事情,目前估值 670 亿美。云计算巨头 AWS 和 Azure 都在跟进它的方法。国内基于图做入侵检测系统的,目前有公开资料的是微步在线和深信服,他们相当于做了部分图关联和溯源的工作。

青藤云安全的万相和蜂巢在入侵检测深耕多年,已经取得了行业认可的安全检测能力,所以选择从图关联和溯源入手,基于 NebulaGraph 结合图技术开发的下一代实时入侵检测系统,先重点解决告警淹没和关联溯源的痛点问题

青藤云安全下一代入侵检测系统

检测原理架构图

如下,核心是上报的攻击告警和部分原始事件统一在图中实时关联。

检测原理架构图

产品效果

经过关联引擎关联处理输出的就是攻击事件,一个攻击事件可能关联多个攻击告警并可视化呈现出来,当前产品效果图如下:

同一次攻击利用恶意文件和木马

同一次攻击利用恶意文件和木马

敏感容器挂载

敏感容器挂载

自定义脚本检测

自定义脚本检测

NebulaGraph 的优势

选择 NebulaGraph 主要基于如下考虑:

  1. 图查询的刚需,特别是关联和溯源时多级进程关系查询,借助 Cypher查询图数据库能够比借助 SQL 在关系数据库中查询多级关系容易多;
  2. 大规模存储,涉及到大量事件和告警的存储;
  3. 高性能查询场景需求,关联需要保证近实时,当前相关查询都在 ms 级别;

得益于 NebulaGraph 的良好性能,关联引擎以近实时的方式入图和计算关联,入图部分是青藤自己基于 Flink 打造的实时入图组件,只需要更改配置文件即可完成图点边映射入图。

下一步研究方向和计划

当前青藤云安全新入侵检测主要支持单机和部分多机场景的关联和溯源,下一步重点是借助图支持更多多机关联的场景,特别是一些典型的安全攻击场景(反弹/横移),进一步以图赋能安全,为客户提供更好的服务。

当然,当前在将 NebulaGraph 应用到图安全应用过程中,也遇到了很多问题,提一些建议供参考。

1.下推优化

在开发过程中,极关心查询效率问题。我们在使用过程中,最大的问题就是下推优化,比如一颗发散的进程树,同时指定根节点和叶子节点,语句书写顺序不同就可能导致查询从叶子节点开始还是根节点开始,查询效率千差万别,最后不得不只指定叶子节点条件强制从叶子节点开始查。

MATCH 性能本质上也是下推优化问题,这个问题遇到也很多,目前我们的做法是对于部分已经查询过语句维持一个缓存池,也注意到官方企业版其实提供了部分缓存功能,这个点要是能考虑加到社区版就好了,是一个实际应用刚需。

2.实时场景一些技术需求点

因为我们是基于 NebulaGraph 做实时关联,一个较大的问题是如何实现一致性和速度的平衡——因为目前 NebulaGraph 实现的是最终一致性,写入图后其实是不知道到底是否真实入图完成。在实际应用中,关联引擎需要在下游轮询等待判断当前的点边是否真正的入图完成。这个对于实际使用和性能都会造成一定影响,是否有更好的方式值得思考。

另一块其实还是效率相关的问题,我们可以看到一些竞品 TigerGraph/TuGraph 都提供了自定义匹配/遍历算法和能力,比如:在我们多机关联场景中就遇到这种需求,目前只能通过拆分多条路径然后拼接起来的实现方式,效率和速度无疑是打折扣的。

3.TOB 部署

另一个,感受较深的是 NebulaGraph 对 TOB 部署的痛点。安全这个行业,目前国内还是走现场部署的较多,特别是国企和政务相关对上 SaaS 相对敏感,那么面临的问题就是效率和成本的问题——

第一个是单机部署,默认生产版本是为云设计的存算分离分布式部署方式,对于 TOB 部署还是太繁琐,且资源占用相对也较其他数据库多。

第二个是 HDD 部署,成本考虑,很多公司特别中小公司安全预算有限,很难提供 SSD 环境,更别说官网要求的大容量 SSD 高配置机器,也就是针对 HDD 和低配机器的优化上需要考虑更多。

以上,为青藤云安全团队工程师文洲带来的分享。


谢谢你读完本文 (///▽///)

要来近距离体验一把图数据库吗?现在可以用用 NebulaGraph Cloud 来搭建自己的图数据系统哟,快来节省大量的部署安装时间来搞定业务吧~ NebulaGraph 阿里云计算巢现 30 天免费使用中,链接来用用图数据库吧~

想看源码的小伙伴可以前往 GitHub 阅读、使用、(^з^)-☆ star 它 -> GitHub;和其他的 NebulaGraph 用户一起交流图数据库技术和应用技能,留下「你的名片」一起玩耍呢~

历经三年多的开发,Meilisearch 1.0 首个完全稳定版已正式发布,可用于生产环境且向前兼容。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Meilisearch 是 Rust 实现的高性能开源搜索引擎,支持方便地集成到任何网站或应用程序,支持自托管 (self-hosting),可作为 Algolia 和 Elasticsearch 的轻量替代方案。Meilisearch 内置了许多实用功能,比如:

  • 快速的输入即搜索 (search-as-you-type) 体验,也称作“即时搜索”
  • 支持冗错/纠错搜索 (typo tolerance)
  • 支持多面搜索 (faceted search)
  • 支持基于地理位置的搜索 (geosearch)
  • 支持多租户 (multi-tenancy)

此外,Meilisearch 提供了一整套完整的 SDK 和库,让开发者便捷地将其连接到流行的编程语言和 Web 工具。Meilisearch 的搜索功能支持所有语言,对任何使用空格分隔单词的语言以及中文、日语、希伯来语、泰语和韩语都进行了特殊优化。

据介绍,1.0 的 CLI 工具不仅进入了稳定状态,还新增了许多破坏兼容性的重要变化,使错误处理程序更加直观。开发团队也表示,在 v2.0.0 发布之前,未来的 CLI 版本不会再有破坏性的更改。

新版本还优化了索引和搜索速度,主要包括以下方面:

  • 优化包含多个长单词的搜索请求的内存使用
  • 提升包含多个单词的搜索请求的排序规则性能
  • 在解释搜索查询时将多词同义词翻译成短语。此项变更优化了结果的相关性,并改进包含多词同义词的搜索查询延迟的稳定性,从而消除 DoS 攻击的来源
  • 优化以短词结尾的搜索请求的排序规则性能
  • 限制在不需要时更新设置引起的重新索引
  • 减少邻近排序规则的增量索引时间
  • 改进软删除 (soft-deletion) 计算

下载地址 & 完整发布说明:https://github.com/meilisearch/meilisearch/releases/tag/v1.0.0

Proxy Server - HackersOnlineClub

Proxy 是 golang 实现的高性能 http、https、websocket、tcp、udp、socks5 代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP 端口映射、SSH 中转、TLS 加密传输、协议转换、DNS 防污染智能代理、前置 CDN/Nginx 反代、代理连接重定向、API 动态调用上级代理、限速限连接数。提供全平台的命令行版本,友好易用的 Windows&Linux&macOS 控制面板,强大的安卓版。

更新内容
1、tcp代理新增tcps加密支持,可以设置加密方法和加密密码,详细说说明可以查看帮助命令:proxy help tcp。
2、优化了kcp协议配置,提高成了连接功率和速度。

更新: v10.7 及以后版本,执行:,即可完成快速更新到最新版。

特色功能

  • 链式代理,程序本身可以作为一级代理,如果设置了上级代理那么可以作为二级代理,乃至 N 级代理。
  • 通讯加密,如果程序不是一级代理,而且上级代理也是本程序,那么可以加密和上级代理之间的通讯,采用底层 tls 高强度加密,安全无特征。
  • 智能 HTTP 代理,HTTPS 代理,SOCKS5 代理,会自动判断访问的网站是否屏蔽,如果被屏蔽那么就会使用上级代理 (前提是配置了上级代理) 访问网站;如果访问的网站没有被屏蔽,为了加速访问,代理会直接访问网站,不使用上级代理。
  • 域名黑白名单,更加自由的控制网站的访问方式。
  • 跨平台性,无论你是 widows,linux,还是 mac,甚至是树莓派,都可以很好的运行 proxy。
  • 多协议支持,支持 HTTP (S),TCP,UDP,Websocket,SOCKS5 代理。
  • TCP/UDP 端口转发。
  • 游戏盾,游戏代理,高仿服务器。
  • 内网穿透,P2P 传输,协议支持 TCP 和 UDP,针对 HTTP 的优化穿透。
  • SSH 中转,HTTP (S),SOCKS5 代理支持 SSH 中转,上级 Linux 服务器不需要任何服务端,本地一个 proxy 即可开心上网。
  • KCP 协议支持,HTTP (S),SOCKS5 代理支持 KCP 协议传输数据,降低延迟,提升浏览体验。
  • 动态选择上级代理,通过外部 API,HTTP (S),SOCKS5,SPS 代理可以实现基于用户或者 IP 的限速,连接数限制,动态获取上级。
  • 灵活的上级分配,HTTP (S),SOCKS5,SPS 代理可以通过配置文件实现基于用户或者 IP 的限速,连接数限制,指定上级。
  • 反向代理,支持直接把域名解析到 proxy 监听的 ip,然后 proxy 就会帮你代理访问需要访问的 HTTP (S) 网站。
  • 透明 HTTP (S) 代理,配合 iptables,在网关直接把出去的 80,443 方向的流量转发到 proxy,就能实现无感知的智能路由器代理。
  • 协议转换,可以把已经存在的 HTTP (S) 或 SOCKS5 或 SS 代理转换为一个端口同时支持 HTTP (S) 和 SOCKS5 和 SS 代理,转换后的 SOCKS5 和 SS 代理如果上级是 SOCKS5 代理,那么支持 UDP 功能,同时支持强大的级联认证功能。
  • 自定义底层加密传输,http (s)spssocks 代理在 tcp 之上可以通过 tls 标准加密以及 kcp 协议加密 tcp 数据,除此之外还支持在 tls 和 kcp 之后进行自定义加密,也就是说自定义加密和 tls|kcp 是可以联合使用的,内部采用 AES256 加密,使用的时候只需要自己定义一个密码即可。
  • 底层压缩高效传输,http (s)spssocks 代理在 tcp 之上可以通过自定义加密和 tls 标准加密以及 kcp 协议加密 tcp 数据,在加密之后还可以对数据进行压缩,也就是说压缩功能和自定义加密和 tls|kcp 是可以联合使用的。
  • 安全的 DNS 代理,可以通过本地的 proxy 提供的 DNS 代理服务器与上级代理加密通讯实现安全防污染的 DNS 查询。
  • 负载均衡,高可用,HTTP (S)SOCKS5SPS 代理支持上级负载均衡和高可用,多个上级重复 – P 参数即可。
  • 指定出口 IP,HTTP (S)SOCKS5SPSTCP 代理支持客户端用入口 IP 连接过来的,就用入口 IP 作为出口 IP 访问目标网站的功能。如果入口 IP 是内网 IP,出口 IP 不会使用入口 IP
  • 支持限速,HTTP (S)SOCKS5SPSTCP 代理支持限速。
  • 支持限连接数,HTTP (S)SOCKS5SPSTCP 代理支持限连接数。

  • SOCKS5 代理支持级联认证。
  • 证书参数使用 base64 数据,默认情况下 – C,-K 参数是 crt 证书和 key 文件的路径,如果是 base64:// 开头,那么就认为后面的数据是 base64 编码的,会解码后使用。
  • 支持客户端 IP 黑白名单,更加安全的控制客户端对代理服务的访问,如果黑白名单同时设置,那么只有白名单生效。socks/http (s)/sps/tcp/udp/dns/ 内网穿透 bridge / 内网穿透 tbridge,都支持客户端 IP 黑白名单。
  • 端口范围批量监听,HTTP (S)SOCKS5SPSTCP 代理支持指定端口范围监听,避免启动过多进程,提高性能。

下载地址:

  • Gitee

  • Github

漏洞描述

ThinkPHP 是一个PHP开发框架,使用面向对象的开发结构和MVC模式。

在受影响版本内存在反序列化漏洞,当应用代码中存在将用户输入的数据进行反序列化操作的端点时,如unserialize($input),具有端点访问权限的攻击者可能利用此缺陷构造恶意payload进而执行任意系统命令。

漏洞名称 Thinkphp 存在反序列化漏洞 漏洞类型 反序列化 发现时间 2023-02-09 漏洞影响广度 一般 MPS编号 MPS-2022-65347 CVE编号 CVE-2022-45982 CNVD编号 –

影响范围

topthink/framework@[6.0.0, 6.0.13]

topthink/framework@[6.1.0, 6.1.1]

修复方案

topthink/framework暂未发布新版本,请关注官方通:https://github.com/top-think/framework/releases

topthink/framework暂未发布新版本,请关注官方通告:https://github.com/top-think/framework/releases

参考链接

https://www.oscs1024.com/hd/MPS-2022-65347

https://gist.github.com/Dar1in9s/aa87dfdb3bbdade360d77f8cca、 POC

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

国内外的用户都在使用云原生技术来提高应用的开发效率和可管理性,不少用户运用开源 Harbor 制品仓库,管理敏捷软件供应链中云原生应用的镜像,包括镜像存储、镜像扫描和镜像签名等功能。

Harbor 已经提供了一些高级的安全功能,例如,对镜像进行扫描,以发现潜在的安全问题。Harbor 的镜像扫描功能本质上属于静态扫描,即通过 Trivy,Clair,雅客云 (Arksec) 等漏洞扫描器(scanner),对镜像进行由事件触发或周期性的扫描。静态扫描可检测到镜像文件中潜在的威胁,但部分有风险的镜像仍有可能通过扫描器的检测,并被部署到 Kubernetes 集群中,从而引入了运行时的风险。

举个例子,Harbor 对某个镜像进行了扫描,检测结果是该镜像达到一定的安全级别,允许它上线运行。过了一段时间,有个新的 CVE 漏洞被发现,恰好该镜像包含了这个漏洞,在漏洞修复前 Harbor 不再容许该镜像上线。但是对已经处于运行态的镜像来说,Harbor 则无能为力。

鉴于 Harbor 重点在云原生应用的静态安全保护,面对日趋严重的 “供应链攻击” 的风险,用户需要提高另一方面的安全能力,即动态安全保护(运行时安全保护)。


为此,我们推出了全新的开源项目 CNSI, 即云原生安全检测器(Cloud Native Security Inspector),项目代号: Narrows。在 Harbor 的基础上,Narrows 增强了动态安全方面的能力,它允许用户对 Kubernetes 集群和其中的工作负载进行运行时的安全态势评估。镜像仓库中的镜像可以在被引入到 Kubernetes 的集群时被扫描,同时 Kubernetes 集群本身的配置和状态一并被扫描并生成安全报告。从而让管理员发现、标记集群中所存在的安全漏洞,并对有漏洞的工作负载进行隔离。

Narrows 所带来的运行时动态安全扫描能力非常关键,它帮助管理员对 Kubernetes 集群和其上工作负载有更好的安全状态控制和感知,而不仅仅是只关注工作负载的生命周期。

Narrows 提供的能力包括:

・      对运行时的漏洞动态检测和感知

・      发现 Kubernetes 集群的错误配置

・      在工作负载运行时,终止进行中的攻击

・      对扫描报告进行汇总、聚合和分析并提供开放的 API 接口

・      与 Harbor 无缝的集成。对于外部公共镜像仓库的镜像,可以自动同步到 Harbor 中,以生成安全数据。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Narrows 与 Harbor 进行了集成,如上图。Narrows 允许用户通过简单的界面来定义对 Kubernetes 集群中工作负载的安全期望,并根据用户指定的扫描器和扫描周期对工作负载进行扫描。对于不满足安全要求的工作负载进行隔离。

当前版本的 Narrows 支持三种扫描器,分别是:

1.Image scanner (镜像扫描器)

将 Kubernetes 集群中镜像的安全漏洞等级与用户期望的安全漏洞等级进行比较,可以对不满足安全预期的工作负载进行隔离。

2.Kubebench scanner (Kubebench 扫描器)

使用 kubebench 对 Kuberentes 集群的配置进行扫描,发现不合理的配置项并提供修改建议。

3.Risk scanner (运行风险扫描器)

对于工作负载中所包含的软件包进行扫描,并提供对应的 CVE 详情。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我们计划通过接入新的安全数据源和引入新的扫描器来增强 Narrows 的检测能力。与此同时,我们将进一步深入研究并扩展对安全漏洞和不安全负载的处理能力。在安全数据分析洞察部分,我们期望可以将多维度的安全数据进行综合汇总,按照不同的场景和用户的偏好进行安全风险排序、筛选和结果呈现。

Narrows 已经由 VMware 公司开源,采用商业化友好的阿帕奇 2.0 软件许可,方便用户作扩展和创新。在社区方面,雅客云 (Arksec) 在 Narrows 最新发布中贡献了排序功能,可结合容器运行时的扫描对安全漏洞进行优先级排序。雅客云也将持续参与 Narrows 项目,计划贡献多项安全能力。


Narrows 已经开源,项目的 Github 地址是:

https://github.com/vmware-tanzu/cloud-native-security-inspector

欢迎广大用户参与到我们的开源项目中,并期待您的使用和反馈。如果您对 Narrows 开源项目感兴趣,希望与我们更密切地合作,或者希望进行测试和试用、提出建议或 bug,请发邮件至 narrows @ vmware.com。

内容来源|公众号:VMware 中国研发中心

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

TigerVNC 1.13.0 现已发布。TigerVNC 是一个高级的 VNC 远程访问的实现,允许你查看运行在网络上另一台计算机上的虚拟桌面环境并与之交互;它是基于 RealVNC 4 和 X.org 代码库的高速 VNC 版本。

重点更新内容如下:

  • 服务器和 native viewer 现在支持 RealVNC 的 RSA-AES 身份验证方法和加密
  • Native viewer 现在已翻译为罗马尼亚语和格鲁吉亚语
  • Native viewer 现在(可选)支持 PiKVM 的 H.264 编码
  • native viewer 的显示设置进行了彻底修改,使其更易于理解
  • Native viewer 现在支持添加过期证书的例外情况
  • 解决了在 macOS 13 上全屏模式在 native viewer 中不起作用的问题
  • 在 1.11.0 中被意外禁用后,Lock key 同步已在 native viewer 中重新启用
  • Xvnc/libvnc.so 现在可以用 Xorg 1.21 构建
  • x0vncserver 在处理不同的服务器和客户端键盘布局方面有了些许改进
  • x0vncserver 现在可以正确处理 zaphod 模式
  • 添加了 Ubuntu 22.04 和 RHEL 9 软件包

二进制文件可从 SourceForge 获得:https://sourceforge.net/projects/tigervnc/files/beta/1.13beta

更多详情可查看更新说明。

Racket v8.8 已发布,Racket(原名 PLT Scheme)是一门通用、多范型,属于 Lisp 家族的函数式程序设计语言,它的设计目之一是为了提供一种用于创造设计与实现其它编程语言的平台,Racket 被用于脚本程序设计、通用程序设计、计算机科学教育和学术研究等不同领域。 Racket 有一个实现平台,包含了运行环境、函数库、即时编译器 (JIT compiler) 等等,还有提供一个以 Racket 本身写成的开发环境 DrRacket(原名 DrScheme)。

新版本主要变化

  • 依赖契约表单支持 #:param 素,该素指定在函数调用的动态范围内设置的参数值的依赖关系
  • 库函数支持权限管理参数
  • 在 DrRacket 的交互窗口中按 <SHIFT>-return 可以更轻松地编辑和输入表达式,而无需将它们发送给评估
  • “如何设计程序”教学语言中的数字比较运算符(= 等)至少需要两个参数
  • 在某些多行情况下使用自定义渲染时,Redex 改进了排版
  • 修复了许多错误,并编写了大量文档

此外还包括许多其他的修复和改进,详情查看发布公告。

Godot Engine 是一个功能丰富的跨平台游戏引擎,可以从一个统一的界面创建 2D 和 3D 游戏。它提供了一套全面的通用工具,因此用户可以专注于制作游戏。游戏可以一键导出到多个平台,包括主要的桌面平台(Linux、macOS、Windows)、移动平台(Android、iOS),以及基于 Web 的平台和游戏机。

由于 Godot 在以前的测试版基础上不断迭代,这些更新说明主要是针对最近的变化(自 Beta 17 以来的变化)。

亮点

  • 大量的无效行为现在被正确验证并在 GDScript 文件中报告(GH-72608)。这包括一些以前看起来工作正常但实际上引擎不支持的行为(比如引擎本地方法的覆盖/遮蔽)。你可以把错误变成警告,或者在需要时完全禁用它们。
  • 由于阴影逻辑不正确, 节点将不再出现比它们应该出现的更暗的颜色
  • 其余报告的子资源 ID 在没有用户输入的情况下被打乱的情况现在应该得到解决。虽然这个问题应该得到解决,但这并不是问题的最终解决方案,团队将在未来的 Godot 版本中继续改进基础系统,以避免这种情况的发生。
  • 现在可以用一个新方法 访问所有全局脚本类的列表。这个方法提供了关于你的自定义类的信息,你无法从 中获取这些信息,以前必须从项目文件或缓存文件中解析。
  • 在某些情况下,即涉及到粒子时,通过调试器的步进可能会非常慢,而且没有反应。这个问题现在应该已经解决了。
  • 翻译资源已被重新组织,以减少其对主资源库大小的影响。团队还为 Godot 4 完成了 Weblate 平台的设置,所以翻译工作可以开始了

更多详情可查看:https://godotengine.org/article/release-candidate-godot-4-0-rc-1/

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

v2.9.7介绍

2.9.7是LiteFlow 2023年的第一个版本。很抱歉这个版本来的晚了一点。

2.9.7提供了1个特性,5个增强,4个Bug修复,1个开源集成特性,总计11个issue的更新。

其中版本特性为迭代器组件,弥补了循环组件之前的不足。

迭代器组件

自从推出了循环组件之后,社区里反应使用体验一直不是很好。其主要因素在于循环组件需要自己去取到当前下标,然后根据下标再去取到对象,这样的过程太过于繁琐。

所以在这个版本,我们增加了一个组件类型:。它也是属于循环组件的一种,结合java的特性,能更快的去循环一个集合。而不用去管下标。

最新的文档已经更新,如果要了解详细用法,可以去相关文档查看。

对规则异常的报错日志进行优化

在以前的规则异常报错中,社区里的同学一直看不懂报错信息,不知道自己写的规则哪里出了问题。

在新的版本中,我们加强了规则报错的日志丰富性,会用箭头指出具体的语法错误以及报错点。这样能更加方便的帮助使用者进行错误规则的排查。

脚本文件的绝对路径支持

LiteFlow的脚本通常大家是写在XML里的,但是对于较多篇幅的脚本时,之前LiteFlow提供了文件脚本这一特性,把脚本单独抽出来作为一个文件,一方面更加方便管理,一方面也有编辑器语法的更加丰富的提示管理。但是很遗憾,在之前的版本中,脚本文件只能定义在项目内。无法定义在本地绝对路径中,而这次,我们弥补了这一缺失。

组件内beforeProcess和afterProcess2个方法的优化

我们在新版本中移除了这2个方法的参数,使这2个方法变成了无参构造。

原因是组件内的任何方法都可以通过关键字来获得任何参数,原先有参数的确是多此一举了。

支持solon框架

我们和开源社区里的solon框架进行了集成,现在LiteFlow也支持solon了。如果有小伙伴使用solon的,也可以使用LiteFlow了。

众多细节点的增强和修复

对于一些不常见的场景,我们的测试用例有的没覆盖到,导致了一些问题,而这些问题在社区进行反应了之后,我们都给予了修复。

我不能保证新的版本是没有BUG的,但是对于大多数主要场景,LiteFlow 2.9.7拥有900多个测试用例,这些测试用例能保证其主要的使用体验和质量。所以,请放心使用。

完整更新列表

 

作者:京东科技 文涛

 

前言


GC是Garbage Collection的缩写,顾名思义垃圾回收机制,即当需要分配的内存空间不再使用的时候,JVM将调用垃圾回收机制来回收内存空间。

那么JVM的垃圾机制是如何工作的呢?

第一步识别出哪些空间不再使用(识别并标记出哪些对象已死);

第二步回收不再使用空间(清除已死对象 )

判断对象是否已死

判断对象是否已死通常有两种方式 ,引用计数法和可达性分析法

引用计数法

给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不能再被使用的。

简单高效,但无法解决循环引用问题,a=b,b=a

引用计数法并没有在产品级的JVM中得到应用

可达性分析法

这个算法的基本思路就是通过一系列的称为“ GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链( Reference Chain),当一个对象到 GC Roots没有任何引用链相连(用图论的话来说,就是从 GC Roots到这个对象不可达)时,则证明此对象是不可用的。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

不过可达性算法中的对象并不是立即死亡的,对象拥有一次自我拯救的机会,对象被系统宣告死亡至少要经历两次标记过程,第一次是经过可达性分析之后没有与GC Roots相连的引用链,第二次是在由虚拟机自动建立的Finalize队列中判断是否需要执行finalize()方法。

HotSopt虚拟机采用该算法。

清除已死对象的方式

标记清除算法

先标记再清除

不足:1 效率问题,标记和清除效率都不高。2 空间问题,产生大量空间碎片

复制算法

内存分两块,A,B

A用完了,将存活对象拷贝到B,A清理掉

代价:内存少了一半。

HotSopt虚拟机用此算法回收新生代。将新生代内存划分为8:1:1的Eden和Survivor解决复制算法内存使用率低的问题

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

标记整理算法

老年代使用,方式和标记清除类似,只是不直接清除,而是将后续对象向一端移动,并清理掉边界以外的内存。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

分代收集算法

分代收集是一个算法方案,整合了以上算法的优点,一般是把Java堆分为新生代和老年代,在新生代中,使用复制算法老年代“标记一清理”或者“标记一整理”

历代垃圾收集器简介

通过上文我们了解了怎样识别垃圾,怎样清理垃圾,接下来,讲ZGC之前,我们回顾一下历代垃圾回收是怎样做的,主要是想给读者一种历史的视角,任何技术都不是凭空产生的,更多的是在前人成果之上进行优化整合

我们先看一个历代JDK垃圾收集器对比表格,以下表格着重说明或引出几个问题:

1 CMS从来未被当作默认GC,且已废弃

2 CMS的思想其实部分被ZGC吸收,CMS已死,但他的魂还在

3 JDK11、JDK17为长期迭代版本,项目中应优先使用这两个版本

版本
发布时间
默认收集器
事件
jdk1.3
2000-05-08
serial

jdk1.4
2004-02-06
ParNew

jdk1.5/5.0
2004-09-30
Parallel Scavenge/serial
CMS登场
jdk1.6/6.0
2006-12-11
Parallel Scavenge/Parallel Old

dk1.7/7.0
2011-07-28
Parallel Scavenge/Parallel Old
G1登场
jdk1.8/8.0
2014-03-18
Parallel Scavenge/Parallel Old

jdk1.9/9.0
2014-09-8
G1
CMS废弃
jdk10
2018-03-21
G1

jdk11
2018-09-25
G1
ZGC登场
jdk12
2019-3
G1
Shenandoah
jdk13
2019-9
G1

jdk14
2020-3
G1
CMS移除
jdk15
2020-9-15
G1
ZGC、Shenandoah转正
jdk16
2021-3-16
G1

jdk17
2021-09-14
G1
ZGC分代
jdk18
2022-3-22
G1

jdk19
2022-9-22
G1


GC分类

我们经常在各种场景听到以下几种GC名词,Young GC、Old GC、Mixed GC、Full GC、Major GC、Minor GC,他们到底什么意思,本人进行了以下梳理

首先GC分两类,Partial GC(部分回收),Full GC

Partial GC:并不收集整个GC堆的模式,以下全是Partial GC的子集

Young GC:只收集young gen的GC

Old GC:只收集old gen的GC。只有CMS的concurrent collection是这个模式

Mixed GC:只有G1有这个模式,收集整个young gen以及部分old gen的GC。

Minor GC:只有G1有这个模式,收集整个young gen

Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。

Major GC:通常是跟full GC是等价的

serial收集器

单线程收集器,“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。它依然是虚拟机运行在 Client模式下的默认新生代收集器。它也有着优于其他收集器的地方:简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说, Serial I收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。

下图彩色部分说明了它的算法,简单粗暴

1 停止用户线程

2 单线程垃圾回收新生代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

ParNew收集器

Parnew收集器其实就是 Serial l收集器的多线程版本。它是许多运行在 Server模式下的虚拟机中首选的新生代收集器,其中有一个与性能无关但很重要的原因是,除了 Serial 收集器外,目前只有它能与CMS收集器配合工作。Pardew收集器在单CPU的环境中绝对不会有比 Serial收集器更好的效果。它默认开启的收集线程数与CPU的数量相同,在CPU非常多(臂如32个)的环境下,可以使用-XX: ParallelGCThreads参数来限制垃圾收集的线程数。

ParNew收集器追求降低GC时用户线程的停顿时间,适合交互式应用,良好的反应速度提升用户体验.

下图彩色部分说明了它的算法,同样简单粗暴

1 停止用户线程

2 多线程垃圾回收新生代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Parallel Scavenge 收集器

Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器。算法的角度它和ParNew一样,在此就不画图解释了

Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量( Throughput)

吞吐量是指用户线程运行时间占CPU总时间的比例

通过以下两种方式可达到目的:

1.在多CPU环境中使用多条GC线程,从而垃圾回收的时间减少,从而用户线程停顿的时间也减少;

2.实现GC线程与用户线程并发执行。

Serial Old收集器

Serial Old是 Serial 收集器的老年代版本,它同样是一个单线程收集器,使用“标记整理”算法。这个收集器的主要意义也是在于给 Client模式下的虚拟机使用。

如果在 Server模式下,那么它主要还有两大用途:

一种用途是在JDK1.5以及之前的版本中与 ParallelScavenge收集器搭配使用,

另一种用途就是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用

下图彩色部分说明了它的算法,同样简单粗暴

1 停止用户线程

2 单线程垃圾回收老年代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Parallel Old收集器

Paralle Old是 Parallel Scavenge收集器的老年代版本,一般它们搭配使用,追求CPU吞吐量,使用多线程和“标记一整理”算法。

下图彩色部分说明了它的算法,同样简单粗暴

1 停止用户线程

2 多线程垃圾回收老年代

3 重启用户线程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

CMS收集器

以上5种垃圾回收原理不难理解,算法之所以如此简单个人理解在当时使用这种算法就够了,随着JAVA的攻城略地,有一种垃圾回收需求出现,即使用尽量短的回收停顿时间,以避免过久的影响用户线程,CMS登场了。

CMS( Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。

想要达到目的,就要分析GC时最占用时间的是什么操作,比较浪费时间的是标记已死对象、清除对象,那么如果可以和用户线程并发的进行,GC的停顿基本就限制在了标记所花费的时间。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如上图,CMS收集器是基于“标记一清除”法实现的,它的运作过程分为4个步骤


初始标记( EMS initial mark) stop the world

并发标记( CMS concurrent mark)

重新标记( CMS remark) stop the world

并发清除( CMS concurrent sweep)

初始标记的作用是查找GC Roots集合的过程,这个过程处理对象相对较少,速度很快。(为什么要进行初始标记:枚举根结点。https://www.zhihu.com/question/)

并发标记是实际标记所有对象是否已死的过程,比较耗时,所以采用并发的方式。

重新标记主要是处理并发标记期间所产生的新的垃圾。重新标记阶段不需要再重新标记所有对象,只对并发标记阶段改动过的对象做标记即可。

优点:

并发收集、低停顿

缺点:

CMS收集器对CPU资源非常敏感。

CMS收集器无法处理浮动垃圾( Floating Garbage),可能出现“Concurrent ModeFailure”失败而导致另一次 Full GC的产生。

“标记一清除”法导致大量空间碎片产生,以至于老年代还有大量空间,却没有整块空间存储某对象。


G1收集器

G1是一款面向服务端应用的垃圾收集器。下文会简单讲解一下它的“特点”和“内存分配与回收策略”,有基础或不感兴趣的同学直接跳到“G1垃圾回收流程”

特点

并行与并发

G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The- World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。

分代收集

与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。

空间整合

与CMS的“标记一清理”算法不同,G1从整体来看是基于“标记一整理”算法实现的收集器,从局部(两个 Region之间)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。

可预测的停顿

这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。

在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域( Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分 Region(不需要连续)的集合

内存分配与回收策略

对象优先在Eden分配

大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次 Minor[ˈmaɪnə(r)] GC

大对象直接进入老年代

所谓的大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组。大对象对虚拟机的内存分配来说就是一个坏消息(比遇到一个大对象更加坏的消息就是遇到一群“朝生夕灭”的“短命大对象”写程序的时候应当避免),经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来“安置”它们。

长期存活的对象将进入老年代

虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次 Minor GC后仍然存活,并且能被 Survivor容纳的话,将被移动到 Survivor空间中,并且对象年龄设为1。对象在 Survivor区中每“熬过”一次 Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认15岁)会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数据-XX : MaxTenuringThreshold设置

动态对象年龄判定

为了能更好地适应不同程序的内存状况,虚拟机并不是水远地要求对象的年龄必须达到了 MaxTenuringThreshold才能晋升老年代,如果在 Survivor空间中相同年龄所有对象大小的总和大于 Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到 MaxTenuringThreshold中要求的年龄。

空间分配担保

在发生 Minor GC之前,虚拟机会先检査老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么 Minor GC可以确保是安全的。如果不成立,则虚拟机会查看 HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次 Minor GC,尽管这次 Minor GC是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次 Full GC.

为什么要担保:

Minor GC后还有大量对象存活且空间不够存放新对象,就要直接在老年代存放

为什么是历次晋升到老年代对象的平均大小:

取平均值进行比较其实仍然是一种动态概率的手段,也就是说,如果某次 Minor GCd存活后的对象突增,远远高于平均值的话,依然会导致担保失败( HandlePromotionFailure)如果出现了 HandlePromotionFailure失败,那就只好在失败后重新发起一次 Full GC。虽然担保失败时绕的子是最大的,但大部分情况下都还是会将 HandlePromotionFailure开关打开,避免 Full GC过于频繁。

eden的大小范围默认是 =【-XX:G1NewSizePercent,-XX:G1MaxNewSizePercent】=【整堆5%,整堆60%】

humongous如果一个对象的大小已经超过Region大小的50%了,那么就会被放入大对象专门的Region中,这种Region我们叫humongous

G1垃圾回收流程

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

网上对G1的回收阶段有不同的说法,参考Oracle JVM工程师的一个说法:

他把整个 G1 的垃圾回收阶段分成了这么三个,第一个叫 Minor GC,就是对新生代的垃圾收集,第二个阶段呢叫 Minor GC + Concurrent Mark,就是新生代的垃圾收集同时呢会执行一些并发的标记,这是第二个阶段,第三个阶段呢它叫 Mixed GC 混合收集,这三个阶段是一个循环的过程。刚开始是这个新生代的垃圾收集,经过一段时间,当老年代的内存超过一个阈值了,它会在新生代垃圾收集的同时进行并发的标记,等这个阶段完成了以后,它会进行一个混合收集,混合收集就是会对新生代、幸存区还有老年代都来进行一个规模较大的一次收集,等内存释放掉了,混合收集结束。这时候伊甸园的内存都被释放掉,它会再次进入新生代的一个垃圾收集过程,那我们先来看看这个新生代的收集 Minor GC。

Minor GC的回收过程(eden满了回收)

选定所有Eden Region放入CSet,使用多线程复制算法将CSet的存活对象复制到Survivor Region或者晋升到Old Region。

下图分7步演示了这个过程

1 初始状态,堆无占用

2 Eden Region满了进行标记

3 将存活对象复制到Survivor Region

4 清理Eden Region

5 Eden Region又满了进行再次标记,此时会连带Survivor Region一起标记

6 将存活对象复制到另一个Survivor Region

7 再次清理Eden Region和被标记过的Survivor Region

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Minor GC结束后自动进行并发标记,为以后可能的Mixed GC做准备

Mixed GC的回收过程(专注垃圾最多的分区)

选定所有Eden Region和全局并发标记计算得到的收益较高的部分Old Region放入CSet,使用多线程复制算法将CSet的存活对象复制到Survivor Region或者晋升到Old Region。

当堆空间的占用率达到一定阈值后会触发Mixed GC(默认45%,由参数决定)

Mixed GC它一定会回收年轻代,并会采集部分老年代的Region进行回收的,所以它是一个“混合”GC。

下图分3步演示了这个过程

1 并发标记所有Region

2 并发复制

3 并发清理



Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



ZGC

ZGC(Z Garbage Collector) 是一款性能比 G1 更加优秀的垃圾收集器。ZGC 第一次出现是在 JDK 11 中以实验性的特性引入,这也是 JDK 11 中最大的亮点。在 JDK 15 中 ZGC 不再是实验功能,可以正式投入生产使用了。

目标低延迟


保证最大停顿时间在几毫秒之内,不管你堆多大或者存活的对象有多少。

可以处理 8MB-16TB 的堆

通过以上历代垃圾回收器的讲解,我们大致了解到减少延迟的底层思想不外乎将stop the world进行极限压缩,将能并行的部分全部采用和用户线程并行的方式处理,然而ZGC更”过分”它甚至把一分部垃圾回收的工作交给了用户线程去做,那么它是怎么做到的呢?ZGC的标记和清理工作同CMS、G1大致差不多,仔细看下图的过程,和CMS特别像,这就是我在上文说的CMS其实并没有真正被抛弃,它的部分思想在ZGC 有发扬。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

ZGC 的步骤大致可分为三大阶段分别是标记、转移、重定位。

标记:从根开始标记所有存活对象

转移:选择部分活跃对象转移到新的内存空间上

重定位:因为对象地址变了,所以之前指向老对象的指针都要换到新对象地址上。

并且这三个阶段都是并发的。

初始转移需要扫描 GC Roots 直接引用的对象并进行转移,这个过程需要 STW,STW 时间跟 GC Roots 成正比。

并发转移准备 :分析最有回收价值GC分页(无STW) 初始转移应对初始标记的数据

并发转移应对并发标记的数据

除了标记清理过程继承了CMS和G1的思想,ZGC要做了以下优化

并发清理(转移对象)

在 CMS 和 G1 中都用到了写屏障,而 ZGC 用到了读屏障。

写屏障是在对象引用赋值时候的 AOP,而读屏障是在读取引用时的 AOP。

比如 ,这个过程就会触发读屏障。

也正是用了读屏障,ZGC 可以并发转移对象,而 G1 用的是写屏障,所以转移对象时候只能 STW。

简单的说就是 GC 线程转移对象之后,应用线程读取对象时,可以利用读屏障通过指针上的标志来判断对象是否被转移。

读屏障会对应用程序的性能有一定影响,据测试,对性能的最高影响达到 4%,但提高了 GC 并发能力,降低了 STW。这就是上面所说的ZGC“过分”地将部分垃圾回收工作交给用户线程的原因。

染色指针

染色指针其实就是从 64 位的指针中,拿几位来标识对象此时的情况,分别表示 Marked0、Marked1、Remapped、Finalizable。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

0-41 这 42 位就是正常的地址,所以说 ZGC 最大支持 4TB (理论上可以16TB)的内存,因为就 42 位用来表示地址

也因此 ZGC 不支持 32 位指针,也不支持指针压缩。

其实对象只需要两个状态Marked,Remapped,对象被标记了,对象被重新映射了,为什么会有M0,M1,用来区分本次GC标记和上次GC标记

以下是标记转移算法说明:

1 在垃圾回收开始前:Remapped

2 标记过程:

标记线程访问

发现对象地址视图是 Remapped 这时候将指针标记为 M0

发现对象地址视图是 M0,则说明这个对象是标记开始之后新分配的或者已经标记过的对象,所以无需处理

应用线程

如果创建新对象,则将其地址视图置为 M0

3 标记阶段结束后

ZGC 会使用一个对象活跃表来存储这些对象地址,此时活跃的对象地址视图是 M0

4 并发转移阶段

转移线程:

转移成功后对象地址视图被置为 Remapped(也就是说 GC 线程如果访问到对象,此时对象地址视图是 M0,并且存在或活跃表中,则将其转移,并将地址视图置为 Remapped )

如果在活跃表中,但是地址视图已经是 Remapped 说明已经被转移了,不做处理。

应用线程:

如果创建新对象,地址视图会设为 Remapped

5 下次标记使用M1

M1 标识本次垃圾回收中活跃的对象

M0 是上一次回收被标记的对象,但是没有被转移,且在本次回收中也没有被标记活跃的对象。

下图展示了Marked,Remapped的过程,

初始化时A,B,C三个对象处于Remapped状态

第一次GC,A被转移,B未被转移,C无引用将被回收

第二次GC,由于A被转移过了(Remapped状态),所以被标记M1,此时恰好B为不活跃对象,将被清理

第三次GC,A又被标记成M0

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

多重映射

Marked0、Marked1和Remapped三个视图

ZGC为了能高效、灵活地管理内存,实现了两级内存管理:虚拟内存和物理内存,并且实现了物理内存和虚拟内存的映射关系 在ZGC中这三个空间在同一时间点有且仅有一个空间有效,利用虚拟空间换时间,这三个空间的切换是由垃圾回收的不同阶段触发的,通过限定三个空间在同一时间点有且仅有一个空间有效高效的完成GC过程的并发操作

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

支持NUMA

NUMA是非一致内存访问的缩写 (Non-Uniform Memory Access,NUMA)

早年如下图:SMP架构 (Symmetric Multi-Processor),因为任一个 CPU 对内存的访问速度是一致的,不用考虑不同内存地址之间的差异,所以也称一致内存访问(Uniform Memory Access, UMA )。这个核心越加越多,渐渐的总线和北桥就成为瓶颈,那不能够啊,于是就想了个办法。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



把 CPU 和内存集成到一个单上,这个就是非一致内存访问 (Non-Uniform Memory Access,NUMA)。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)



ZGC 对 NUMA 的支持是小分区分配时会优先从本地内存分配,如果本地内存不足则从远程内存分配。

ZGC优劣

综上分析,ZGC在战略上沿用了上几代GC的算法策略,采用并发标记,并发清理的思路,在战术上,通过染色指针、多重映射,读屏障等优化达到更理想的并发清理,通过支持NUMA达到了更快的内存操作。但ZGC同样不是银弹,它也有自身的优缺点,如下

优势:

1、一旦某个Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Region的引用都被修正后才能清理,这使得理论上只要还有一个空闲Region,ZGC就能完成收集。

2、颜色指针可以大幅减少在垃圾收集过程中内存屏障的使用数量,ZGC只使用了读屏障。

3、颜色指针具备强大的扩展性,它可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程相关的数据,以便日后进一步提高性能。

劣势:

1、它能承受的对象分配速率不会太高

ZGC准备要对一个很大的堆做一次完整的并发收集。在这段时间里面,由于应用的对象分配速率很高,将创造大量的新对象,这些新对象很难进入当次收集的标记范围,通常就只能全部当作存活对象来看待——尽管其中绝大部分对象都是朝生夕灭的,这就产生了大量的浮动垃圾。如果这种高速分配持续维持的话,每一次完整的并发收集周期都会很长,回收到的内存空间持续小于期间并发产生的浮动垃圾所占的空间,堆中剩余可腾挪的空间就越来越小了。目前唯一的办法就是尽可能地增加堆容量大小,获得更多喘息的时间。

2、吞吐量低于G1 GC

一般来说,可能会下降5%-15%。对于堆越小,这个效应越明显,堆非常大的时候,比如100G,其他GC可能一次Major或Full GC要几十秒以上,但是对于ZGC不需要那么大暂停。这种细粒度的优化带来的副作用就是,把很多环节其他GC里的STW整体处理,拆碎了,放到了更大时间范围内里去跟业务线程并发执行,甚至会直接让业务线程帮忙做一些GC的操作,从而降低了业务线程的处理能力。

总结

综上,其实ZGC并不是一个凭空冒出的全新垃圾回收,它结合前几代GC的思想,同时在战术上做了优化以达到极限的STW,ZGC的优秀表现有可能会改变未来程序编写方式,站在垃圾收集器的角度,垃圾收集器特别喜欢不可变对象,原有编程方式鉴于内存、GC能力所限使用可变对象来复用对象而不是销毁重建,试想如果有了ZGC的强大回收能力的加持,是不是我们就可以无脑的使用不可变对象进行代码编写

参考:

《深入理解java虚拟机》

《JAVA性能权威指南》

JDK 发展至今的垃圾回收机制

全网最全JDK1~JDK15十一种JVM垃圾收集器的原理总结

为什么CMS需要初始标记?

一步一图带你理清G1垃圾回收流程

美团面试官问我:ZGC 的 Z 是什么意思?

ZGC有什么缺点?

ZGC 原理是什么,它为什么能做到低延时?

本文档示意图原型:https://www.processon.com/view/link/63771dbb3a840c4027

Hermes 是一个由 HashiCorp 创建的开源文档管理系统,用于帮助简化写作和文档流程。据介绍,HashiCorp 内部员工使用 Hermes 编写、审查、批准、发现和处理已被弃用的文档。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Hermes 后端使用 Golang,前端使用 Ember.js,并使用 PostgreSQL 数据库进行存储,以及使用 Algolia 来增强其搜索功能。它还利用多项 Google Workspace 服务来创建和修改文档、发送电子邮件等。

Hermes 支持 Google Workspace,用户只要登录 Hermes,他们就可以使用 Google Docs 创建文档草稿。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

近日,OSCHINA 和 Gitee 联合发布了
《2022 中国开源开发者报告》
报告对中国的开源创业企业进行了调查,得出了一些有趣的结论。还有更多关于开源创企融资、开源商业化模式,以及创始人创业回报预期、未来市场预期等情况,请移步至官网了解: https://gitee.com/report/china-open-source-2022
 
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2019 年是创业高峰

最早的一家开源创企成立于 2012 年;2016 年起,开源创业浪潮出现,并于 2019 年达到巅峰;刚刚过去的 2022 年,有 2 家企业宣告成立。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

数据技术创业是大热门

在数据库、大数据、AI、云计算、DevOps、操作系统、中间件等多个技术领域中,围绕数据技术进行创业的企业最多,其中,22.86% 的企业集中在数据库领域,14.29%的企业集中在大数据领域。紧随其后的是云计算和 AI 领域,分别有 17.14% 的企业分布。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

灵活办公情况

开源创企内部或多或少选择了部分人员灵活办公的模式。其中,灵活办公人员在 10 % 以内的企业,占比 40.91 %;灵活办公人员在 10 % -19 % 之间的企业,占比为18.18 % ;灵活办公人员达到 80 % 的企业,占比仅 4.55 % 。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

创始人精力分配

整体来看,在研发、运营和销售三个方向中,创始人精力分配顺序为:研发>运营>销售。
以研发为例,投入精力达到 5 星的创始人占比为 54.55%;投入精力达到 4 星的创始人占比为 18.18%;投入精力达到 3 星的创始人占比为 9.09%;投入精力为 2 星的创始人占比为 13.64;投入精力为 1 星的创始人占比为 4.55%。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

开源项目所有权归属

81.82% 的项目所有权归属该公司,36.36% 的项目归中立的软件基金会所有。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
*一家企业可能同时运营多个项目,不同项目所有权不同,因此本题为多选题。对于多选题百分比相加可能超过百分之一百。
 

研发投入情况

在开源项目研发投入方面,研发投入占比超 40% 的企业,达八成。其中,投入在 41 % -60 % 间的企业占比为 31.82 %,投入在 61 % -80 % 间的企业占比为 22.73 %,投入超 80%的企业占比为 27.27% 。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Apache 2.0 许可证是最大赢家

在 22 家开源创企的核心开源项目中,有 21 个开源项目使用了一个开源许可证,其中 18 个使用了 Apache 2.0 许可证,另有 3 个项目分别选择了 BSD、MIT、AGPL 许可证;此外还有一个开源项目采用 Apache 2.0 + SSPL 双许可模式。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
 

微软和 Adob​​e 达成合作,计划将 Adob​​e Acrobat PDF 渲染引擎直接集成到 Edge 浏览器中,取代现有的 PDF 引擎。

包含这个新的 PDF 引擎的 Edge 浏览器版本预计将于今年 3 月份推出,带有旧版引擎的 Microsoft Edge PDF 解决方案则计划于 2024 年 3 月停止支持。这种分阶段推出的方式,将为用户提供充足的时间来进行相关测试。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

公告称,通过使用 Adob​​e Acrobat 的 PDF 渲染引擎为内置 PDF 阅读器提供动力,两家公司共同增强了用户对 Microsoft Edge 的 PDF 体验和价值期望。新的 PDF 引擎将为用户提供更丰富的渲染以获得更准确的颜色和图形、改进的性能、为 PDF 处理提供强大的安全保障,以及更的可访问性;且这些功能都将继续保持免费。

借助 Adob​​e Acrobat 功能为 Edge 中的 PDF 体验提供支持,Windows 10 和 Windows 11 用户可以在 Microsoft Edge Web 浏览器中使用 Adob​​e 的 PDF 功能,而无需下载或切换到单独的应用程序。

想要更高级的数字文档功能(例如编辑文本和图像、将 PDF 转换为其他文件格式以及合并文件的能力)的用户则需要购买 Acrobat 订阅,然后通过浏览器扩展在 Microsoft edge 中实现。

更多详情可查看官方公告。

去年 9 月,欧盟提出了一项网络弹性法案 (CRA) ,目标是“加强网络安全规则,以提供更安全的硬件和软件产品”。但该法案随即引起了公众的批评,因为它可能会对开源生态产生严重的影响。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这个法案可以理解为软件产品的 CE (欧盟认证)标准,有四个具体目标:

  • 要求软件制造商提高“全生命周期”数字素产品的安全性
  • 提供一个“一致的网络安全框架”来衡量软件的安全合规性
  • 提高软/硬件产品的“数字素”的安全属性透明度
  • 让客户可以“放心使用带有数字素的产品”

总而言之,这是一套新的欧盟软件安全认证规定。对于软件开发商和硬件制造商,它将增加新的网络安全要求、合格评定费、合格认证文件和报告义务等直接合规成本。当然,这些成本毫无意外地会转嫁到消费端,法案中如此描述:

这些额外成本是合规总成本的一部分,包括对企业和公共政务的负担,估计为 290 亿欧(315.4 亿美),随之而来的是消费者侧的软件价格将会上涨。

但每年在网络安全事件中受到的损失将减少 180 至 2900 亿欧。

但对于大部分为爱发电的开源软件作者来说,这无疑是一项疯狂的规定,数年如一日的辛苦付出没有回报也就算了,还要自掏腰包来进行认定?该法案公布之后, 一些开源社区的领导人对其作出了严厉的评价,并提供了大量的意见反馈。

开源倡议组织 OSI 标准主管 Simon Phipps 亦提出了批评,认为该立法“可能会损害开源”,因为其关于开源软件部分的文本描述含糊不清,且“立法者完全不了解开源社区的实际运作方式”。目前 OSI 已向欧盟委员会提交了反馈,要求“就法案正文要求的开源例外情况开展进一步工作”,希望“任何不直接从软件商业化部署中受益的参与者”都可以免除合规责任。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Eclipse 基金会主任 Mike Milinkovich 认为: CRA 法案可能会从根本上改变整个开源生态系统的运转方式。现在大部分开源软件都是免费提供,可用于任何目的,且可以修改和进一步分发,但原作者、贡献者或分销商不提供任何保证或承担任何责任。如果通过立法的方式强制改变这种生态,可能会对欧洲的创新经济造成意想不到的后果。

此外,Milinkovich 还指出,CRA 会限制未完成开发的软件,未完全开发的软件只能用于测试用途,这又是一项对现有开源生态具有强烈破坏性的规定。在开源社区中,使用临时构建的软件版本是很常见的行为,且现有的开源许可证也不会限制软件的用途。

互联网协会执行顾问 Olaf Kolkman 也表达了担忧,他表示“应该修改法规,以明确在开源许可证下生产,并在非营利基础上分发的软件不在该法规范围内”。

目前欧盟委员会还在针对公众的意见不断修改这份法案,最新的修订时间是 23 年 1 月 30 日。如果处理不当,该法规可能会导致欧盟地区无法访问 Central、npm、PyPi 等常用的库系统,这对于欧盟和整个开源生态系统都将是灾难性的打击。

CRA 法案下载地址:https://ec.europa.eu/newsroom/dae/redirection/document/89543

摘要:用户创建hash分布表,使用pbe方式执行使用分布列作为查询条件的语句时报错

本文分享自华为云社区《GaussDB(DWS)现网案例之collation报错》,作者: 你是猴子请来的救兵吗 。

用户创建hash分布表,使用pbe方式执行使用分布列作为查询条件的语句时报错,ERROR: could not determine which collation to use for string hashing

问题背景

内核版本:GaussDB 8.1.3
业务框架:jalor + mybatis

问题描述:用户创建hash分布表,使用pbe方式执行使用分布列作为查询条件的语句时报错,ERROR: could not determine which collation to use for string hashing

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

根因分析

源表为hash分布表,当使用分布列作为查询条件时,可以通过节点分区剪枝提升性能;

分布列类型为nvarchar2(100),构造pbe剪枝语句时,需要对传入变量进行类型转换和精度转换,未正确更新collation,导致执行报错

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

场景复现

建表数据


场景1:client + p/e


场景2:jdbc + p/b/e


场景3:jalor + *Dao.*.xml


规避办法

任选一种既可,推荐第一种,改动小影响小

1,将分布列类型nvarchar2(n)修改为nvarchar2或varchar(n)

2,使用拼接sql的办法执行语句,而不是pbe

3,语句中指定collate子句,如select c2 from t1 where c1 collate “default” = ?;

4,升级版本

知识小结

问题条件:

1,内核版本8.1.3 ≤ version ≤ 8.1.3.300

2,分布列包含nvarchar2(n)类型字段

3,使用pbe的方式执行语句

4,语句过滤条件包含所有分布列

规避方法:

打破以上任一条件即可规避

 

关注,第一时间了解华为云新鲜技术~

摘要:本示例围绕真实AI需求场景,介绍VSCode一键接入Notebook体验算法套件快速完成水表读数的使用流程。

本文分享自华为云社区《VSCode一键接入Notebook体验算法套件快速完成水表读数》,作者:HWCloudAI。

本示例围绕真实AI需求场景,介绍VSCode一键接入Notebook体验算法套件快速完成水表读数的使用流程。

算法开发套件中目前提供自研(ivg系列)和开源(mm系列)共两套算法资产,可应用于分类、检测、分割和OCR等任务中。本示例中将组合使用自研分割算法(ivgSegmentation)和开源OCR算法(mmOCR)完成水表读数识别项目,并使用算法开发套件将其部署为华为云在线服务。

说明:

本案例教程仅适用于“华北-北京四”区域,新版Notebook。

准备数据

  1. 登录OBS控制台,创建OBS对象桶,区域选择“华北-北京四”。
  2. 登录ModelArts控制台,选择控制台区域为“华北-北京四”。
  3. 在“全局配置”页面查看是否已经配置授权,允许ModelArts访问OBS。如果没有配置授权,请参考配置访问授权(全局配置)添加授权。
  4. 分别下载本案例的数据集,水表表盘分割数据集水表表盘读数OCR识别数据集到OBS桶中,OBS路径示例如下

obs://{OBS桶名称}/water_meter_segmentation 水表表盘分割数据集

obs://{OBS桶名称}/water_meter_crop 水表表盘读数OCR识别数据集

说明:

从AIGallery下载数据集免费,但是数据集存储在OBS桶中会收取少量费用,具体计费请参见OBS价格详情页案例使用完成后请及时清除资源和数据。

准备开发环境

在“ModelArts控制台 > 开发环境 > Notebook(New)”页面中,创建基于pytorch1.4-cuda10.1-cudnn7-ubuntu18.04镜像,类型为GPU的Notebook,具体操作请参见创建Notebook实例章节。

本案例需要使用VS Code 远程连接Notebook,需要开启SSH远程开发。

图1 创建Notebook实例

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

1.实例的密钥文件需要下载至本地的如下目录或其子目录中:

Windows:C:Users{{user}}

Mac/Linux: Users/{{user}}

2.在ModelArts控制台->开发环境 Notebook,单击“操作”列的“更多 > VS Code接入”。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如果本地已安装VS Code,请单击“打开”,进入“Visual Studio Code”页面。

如果本地未安装VS Code,请根据实际选择“win”或“其他”下载并安装VS Code。VS Code安装请参考安装VS Code软件

如果用户之前未安装过ModelArts VS Code插件,此时会弹出安装提示,请单击“Install and Open”进行安装;如果之前已经安装过插件,则不会有该提示,请跳过此步骤,直接执行后面步骤

安装过程预计1~2分钟,安装完成后右下角会弹出对话框,请单击“Reload Window and Open”。

在弹出的提示中,勾选“Don’t ask again for this extension”,然后单击”Open”。

3.远程连接Notebook实例。

  • 远程连接执行前,会自动在(Windows:C:Users{{user}}.ssh或者downloads,Mac/Linux: Users/{{user}}/.ssh或者downloads)目录下根据密钥名称查找密钥文件,如果找到则直接使用该密钥打开新窗口并尝试连接远程实例,此时无需选择密钥。
  • 如果未找到会弹出选择框,请根据提示选择正确的密钥。
  • 如果密钥选择错误,则弹出提示信息,请根据提示信息选择正确密钥。
  • 当弹出提醒实例连接失败,请关闭弹窗,并查看OUTPUT窗口的输出日志,请查看FAQ并排查失败原因。

使用算法套件进行开发

Step1 创建算法工程

1.成功接入之后,在VS Code页面文件->打开文件夹,选择如下文件夹打开

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.新建终端

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

3.在work目录下执行


命令创建工程,根据提示输入工程名称,例如:water_meter。然后直接回车选择默认参数,并选择跳过资产安装步骤(选择6)。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

4.执行以下命令进入工程目录。


5.执行以下命令拷贝项目数据到Notebook中。


说明:

{obs_dataset_path}路径为Step1 准备数据中下载到OBS中的数据集,比如“obs://{OBS桶名称}/water_meter_segmentation”和“obs://{OBS桶名称}/water_meter_crop”

Step2 使用deeplabv3完成水表区域分割任务

1.首先安装ivgSegmentation套件。


如果提示ivgSegmentation版本不正确,可以通过命令python manage.py list algorithm查询版本。

2.安装ivgSegmentation套件后,在界面左侧的工程目录中进入“https://www.xujun.org/algorithms/ivgSegmentation/config/sample”文件夹中查看目前支持的分割模型,以sample为例(sample默认的算法就是deeplabv3),文件夹中包括config.py(算法外壳配置)和deeplabv3_resnet50_standard-sample_512x1024.py(模型结构)。

3.表盘分割只需要区分背景和读数区域,因此属于二分类,需要根据项目所需数据集对配置文件进行修改,如下所示:

修改https://www.xujun.org/algorithms/ivgSegmentation/config/sample/config.py文件。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

修改完后按Ctrl+S保存。

4.修改https://www.xujun.org/algorithms/ivgSegmentation/config/sample/deeplabv3_resnet50_standard-sample_512x1024.py文件。


Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

5.修改完按Ctrl+S保存。

6.在water_meter工程目录下,安装deeplabv3预训练模型。


7.训练分割模型。(推荐使用GPU进行训练)


训练好的模型会保存在指定位置中,默认为output/deeplabv3_resnet50_standard-sample_512x1024/checkpoints/中。

8.验证模型效果。

模型训练完成后,可以在验证集上计算模型的指标,首先修改配置文件的模型位置。

修改https://www.xujun.org/algorithms/ivgSegmentation/config/sample/config.py。


9.模型推理。

模型推理能够指定某一张图片,并且推理出图片的分割区域,并进行可视化,首先需要指定需要推理的图片路径。

修改https://www.xujun.org/algorithms/ivgSegmentation/config/sample/config.py


执行如下命令推理模型效果。


推理输出的图片路径在https://www.xujun.org/output/deeplabv3_resnet50_standard-sample_512x1024下。

10.导出SDK。

算法开发套件支持将模型导出成一个模型SDK,方便进行模型部署等下游任务。


Step3 水表读数识别

1.首先安装mmocr套件。


2.安装mmocr套件后,https://www.xujun.org/algorithms/mmocr/config/textrecog文件夹中包括config.py(算法外壳配置),需要根据所需算法和数据集路径修改配置文件。以下以robust_scanner算法为例。

修改https://www.xujun.org/algorithms/mmocr/algorithm/configs/textrecog/robustscanner_r31_academic.py,


3.安装robust_scanner预训练模型。


4.训练OCR模型。

初次使用mmcv时需要编译mmcv-full,该过程较慢,可以直接使用官方预编译的依赖包。

预编译包URL: https://download.openmmlab.com/mmcv/dist/cu101/torch1.6.0/index.html


将https://www.xujun.org/algorithms/mmocr/config/textrecog/config.py中的epoch(迭代数量)改为2,如下图所示:


训练好的模型会保存在指定位置中,默认为output/${algorithm}中。

5.验证模型效果。

模型训练完成后,可以在验证集上计算模型的指标,首先修改配置文件的模型位置。

修改https://www.xujun.org/algorithms/mmocr/config/textrecog/config.py


6.模型推理。

模型推理能够指定某一张图片,并且推理出图片的分割区域,并进行可视化。首先需要指定待推理的图片路径,修改algorithms/mmocr/config/textrecog/config.py文件,具体如下。

修改https://www.xujun.org/algorithms/mmocr/algorithm/configs/textrecog/robust_scanner/config.py


推理输出的图片路径在output/robustscanner_r31_academic/vis下

7.导出SDK。


Step4 部署为在线服务

本次展示仅部署OCR服务, 包括本地部署和线上部署, 部署上线后调用部署服务进行本地图片的推理,获取水表的预测读数。部署在线服务,需要指定OBS桶以便保存部署所需要的文件。

1.在algorithms/mmocr/config/textrecog/config.py文件中配置OBS桶,即obs_bucket=<please input your own bucket here>。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.执行下述命令:


此处,查看部署成功的在线服务

Step5 清除资源和数据

通过此示例学习完成创建算法套件流程后,如果不再使用,建议您清除相关资源,避免造成资源浪费和不必要的费用。

  • 停止Notebook:在“Notebook”页面,单击对应实例操作列的“停止”。
  • 删除数据:此处前往OBS控制台,删除上传的数据,然后删除文件夹及OBS桶。

 

关注,第一时间了解华为云新鲜技术~

摘要:企业版性能指标达到业界TOP1,行业领先30%,内核态实现真正多线程。

一.背景介绍

近年来,随着各行业业务需求急速增加,数据量和并发访问量呈指数级增长,原来只能依附于关系型数据库的传统“缓存”逐渐难以支撑上层业务,开源Redis也面临着如“容量有限”、 “可靠性有限”、 “数据重复拷贝,成本高,效率低” 等问题。为了解决开源Redis痛点以及自运维数据库问题,华为云推出了分布式缓存服务(Distributed Cache Service,简称DCS)。

二.关于分布式缓存服务DCS

分布式缓存服务(Distributed Cache Service)它是华为云提供的一款高速内存数据处理引擎,兼容了Redis缓存引擎,提供即开即用、安全可靠、弹性扩容、便捷管理的在线分布式缓存能力,满足用户高并发及数据快速访问的业务诉求。DCS企业版完全兼容Redis6,提供主备实例类型,可选择4GB~1TB不同规格,支持异常自动切换、一键在线扩容,无缝配合业务规模发展,支持跨AZ容灾,超过64GB可转化为SSD存储,成本低,持久化能力更强。

三.企业版&基础版能力对比

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
  • KeyDB 是 Redis 的高性能分支,专注于多线程、内存效率和高吞吐量,首次实现了Redis真正的“多线程”,且对 Redis 100%兼容。
  • KeyDB将Redis原来的主线程拆分成了多个worker线程。每个worker线程都负责监听端口,accept请求,读取数据和解析协议,是“真正的多线程”。
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
  • KeyDB的性能比Redis高出5倍,DCS企业版超出业界30%性能,达到40W QPS
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)
  • 企业版性能抖动与开源版本对比有数倍提升
Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

更多华为云DCS信息请查看官网:https://www.huaweicloud.com/devcloud/index.html

 

关注,第一时间了解华为云新鲜技术~

DevOps 通常被描述为无限循环,而 DataOps 被描述为交叉的价值和创新管道

关于DataOps的一个常见误解是它只是将DevOps 应用于数据分析。虽然在语义上有点误导,但“DataOps”这个名字有一个积极的属性。它表明数据分析可以实现软件开发通过 DevOps 实现的目标。也就是说,当数据团队使用新工具和方法时,DataOps 可以在质量和周期时间上产生一个数量级的改进。DataOps 实现这些收益的具体方式反映了数据团队(相对于使用 DevOps 的软件开发团队)的独特人员、流程和工具特征。这是我们对 DataOps 和 DevOps 之间显着和细微差异的深入探讨。

01 DataOps 的知识遗产

DevOps是一种使用自动化加速构建生命周期(以前称为发布工程)的软件开发方法。DevOps通过利用按需 IT 资源(基础设施即代码)以及代码的自动化集成、测试和部署,专注于软件的持续集成和持续交付。软件开发和 IT 运营(“开发”和“运营”)的这种合并缩短了部署时间,缩短了上市时间,最大限度地减少了缺陷,并缩短了解决问题所需的时间。

使用DevOps,领先的公司已经能够将他们的软件发布周期从几个月缩短到(字面上)几秒钟。这使他们能够在快节奏的新兴市场中成长并处于领先地位。谷歌、亚马逊和许多其他公司现在每天多次发布软件。通过提高代码发布的质量和周期时间,DevOps 应该为这些公司的成功赢得很多赞誉。

优化代码构建和交付只是数据分析更大难题的一部分。DataOps 旨在减少数据分析的端到端周期时间,从想法的起源到创造价值的图表、图形和模型的文字创建。除了工具之外,数据生命周期还依赖于人。要使 DataOps 有效,它必须管理协作和创新。为此,DataOps 将敏捷开发引入数据分析中,以便数据团队和用户更高效地协同工作。

在敏捷开发中,数据团队以称为“冲刺”的短增量发布新的或更新的分析。随着创新的快速发生,团队可以不断地重新评估其优先事项并更轻松地适应不断变化的需求。使用瀑布式项目管理方法,这种类型的响应是不可能的,这种方法将团队锁定在一个漫长的开发周期中,最后只有一个“大爆炸”交付。

 Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

研究表明,当敏捷开发取代传统的瀑布顺序方法时,敏捷软件开发项目完成得更快且缺陷更少。敏捷方法在需求快速变化的环境中特别有效——这是数据分析专业人员所熟知的情况。在 DataOps 环境中,敏捷方法使组织能够快速响应客户需求并加快实现价值的时间。

敏捷开发和 DevOps 为数据分析增加了重要价值,但 DataOps 还有一个主要组成部分。敏捷和 DevOps 与分析开发和部署相关,而数据分析还管理和编排数据管道。数据不断地从管道的一侧进入,通过一系列步骤并以报告、模型和视图的形式退出。数据管道是数据分析的“操作”端。将数据管道概念化为必须管理质量、效率、约束和正常运行时间的生产线是有帮助的。为了完全接受这种制造思维,我们将此管道称为“数据工厂”。”

在 DataOps 中,通过操作的数据流是一个重要的关注领域。DataOps 编排、监控和管理数据工厂。一种特别强大的精益制造工具是统计过程控制(SPC)。SPC 测量和监控数据管道的数据和操作特征,确保统计数据保持在可接受的范围内。当 SPC 应用于数据分析时,它会显着提高效率、质量和透明度。SPC 到位后,流经操作系统的数据被验证为正常工作。如果发生异常情况,数据分析团队将通过自动警报第一个知道。

虽然“DataOps”这个名称暗示它从 DevOps 中借用最多,但这三种方法——敏捷、DevOps 和统计过程控制——构成了 DataOps 的知识遗产。敏捷管理分析开发,DevOps 优化代码验证,构建和交付新的分析,SPC 协调和监控数据工厂。图 1 说明了敏捷、DevOps 和统计流程控制如何流入 DataOps。

您可以在长达一个世纪的思想演变的背景下查看 DataOps,这些思想改进了人们管理复杂系统的方式。它始于像Demming和统计过程控制这样的先驱——这些想法逐渐以敏捷、DevOps 和现在的 DataOps 的形式进入技术领域。

02 DevOps与DataOps — 人为因素

如上所述,DataOps 与管理人员和工具一样重要。DataOps 和 DevOps 之间的一个细微差别与利益相关者的需求和偏好有关。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

DevOps 的创建是为了满足软件开发人员的需求。开发工程师喜欢编码并拥抱技术。学习新语言或部署新工具的要求是机会,而不是麻烦。他们对代码创建、集成和部署的所有细节都非常感兴趣。DevOps 包含复杂性。

DataOps 用户通常与此相反。他们是专注于构建和部署模型和可视化的数据科学家或分析师。科学家和分析师通常不像工程师那样精通技术。他们专注于领域专业知识。他们感兴趣的是让模型更具预测性或决定如何最好地视觉呈现数据。用于创建这些模型和可视化的技术只是达到目的的一种手段。数据专业人员最乐于使用一两个工具——除此之外的任何工具都会增加不受欢迎的复杂性。在极端情况下,复杂性会超出他们的管理能力。DataOps 承认数据专业人员生活在一个多工具、异构的世界中,它试图让这个世界对他们来说更易于管理。

03 DevOps与DataOps — 流程差异

通过查看数据分析开发和生命周期流程,我们可以开始了解数据专业人员面临的独特复杂性。我们发现,与软件开发人员相比,数据分析专业人员面临着既相似又独特的挑战。

DevOps 生命周期通常使用无限符号形状的图表来说明 – 参见图 3。周期的结束(“计划”)反馈到开始(“创建”),并且过程无限迭代。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

DataOps 生命周期共享这些迭代属性,但重要的区别是 DataOps 由两个活动的相交管道组成(图 4)。上面描述的数据工厂是一个管道。另一个管道控制数据工厂的更新方式——创建新分析并将其部署到数据管道中。

数据工厂将原始数据源作为输入,并通过一系列精心安排的步骤产生分析见解,为组织创造“价值”。我们称之为“价值管道”。DataOps 自动化编排,并使用SPC监控流经价值管道的数据质量。

“创新管道”是将新的分析思想引入价值管道的过程。创新管道在概念上类似于 DevOps 开发过程,但经过仔细研究,有几个因素使 DataOps 开发过程比 DevOps 更具挑战性。图 4 显示了价值和创新管道的简化视图。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

04 DevOps与DataOps — 开发和部署流程

DataOps 建立在 DevOps 开发模型之上。如图5 所示,DevOps 流程包括软件开发项目常见的一系列步骤:

开发——创建/修改应用程序

构建——组装应用程序组件

测试——在测试环境中验证应用程序

部署——将代码转换为生产

运行——执行应用程序

DevOps 引入了两个基本概念:持续集成(CI) 和持续部署(CD)。CI 在开发环境中不断构建、集成和测试新代码。构建和测试是自动化的,因此它们可以快速重复地进行。这样可以快速识别和解决问题。图5 说明了 CI 如何包含 DevOps 的构建和测试过程阶段。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

CD 是一种部署或交付软件的自动化方法。一旦应用程序通过了所有资格测试,DevOps 就会将其部署到生产环境中。CI 和 CD 一起解决了阻碍敏捷开发的主要约束。在 DevOps 之前,敏捷创造了一系列快速的更新和创新,这些更新和创新会在手动集成和部署过程中停滞不前。借助自动化 CI 和 CD,DevOps 使公司能够每天多次更新他们的软件。

05 DataOps 中编排的二性

需要注意的是,“编排”在图 5 所示的 DataOps 流程中发生了两次。正如我们上面解释的,DataOps 编排数据工厂(价值管道)。数据工厂由一个包含许多步骤的管道过程组成。想象一个复杂的有向无环图(DAG)。“协调器”可以是一个软件实体,它控制步骤的执行、遍历 DAG 并处理异常。例如,编排器可能会创建容器、使用上下文相关参数调用运行时进程、在阶段之间传输数据以及“监控”管道执行。数据工厂的编排是图 6 中 DataOps 流程中的第二个“编排”。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如上所述,创新管道具有数据管道的代表性副本,用于在部署到生产之前测试和验证新分析。这是与“测试”结合并在“部署”新分析之前发生的编排——如图 7 所示。

编排发生在价值和创新管道中。同样,测试在 DataOps 中扮演着双重角色。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

06 DataOps 中测试的二性

DataOps 中的测试在价值和创新管道中都有作用。在价值管道中,测试监控流经数据工厂的数据值,以捕捉异常或标记统计规范之外的数据值。在创新管道中,测试会在部署新分析之前对其进行验证。

在 DataOps 中,测试以数据或代码为目标。我们使用图 8 讨论了这个概念。流经价值管道的数据是可变的,并且受统计过程控制和监控。测试针对的是不断变化的数据。另一方面,价值管道中的分析是固定的,只能使用正式的发布流程进行更改。在价值管道中,分析受到修订控制,以最大限度地减少可能影响数据工厂的任何服务中断。

在创新管道中,代码是可变的,数据是固定的。分析被修改和更新直到完成。沙盒设置完成后,数据通常不会更改。在创新管道中,测试针对的是代码(分析),而不是数据。在将新代码推广(合并)到生产环境之前,所有测试都必须通过。一个好的测试套件可以作为一种自动化的影响分析形式,在部署之前运行在任何代码更改上。

一些测试同时针对数据和代码。例如,确保数据库具有正确行数的测试有助于您的数据和代码协同工作。最终,数据测试和代码测试都需要整合到一个集成的管道中,如图 4 所示。DataOps 使代码和数据测试能够协同工作,因此始终保持高质量。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

当工程师加入软件开发团队时,他们的第一步就是创建一个“沙箱”。沙盒是一个隔离的开发环境,工程师可以在其中编写和测试新的应用程序功能,而不会影响正在并行开发其他功能的队友。软件开发中的沙盒创建通常很简单——工程师通常会从队友那里收到一堆脚本,并且可以在一两天内配置一个沙盒。这是使用 DevOps 的团队的典型思维方式。

从工具和数据的角度来看,数据分析中的沙箱通常更具挑战性。首先,与典型的软件开发团队相比,数据团队总体上倾向于使用更多的工具。有数以千计的工具、语言和供应商用于数据工程、数据科学、商业智能、数据可视化和治理。如果没有大多数软件开发团队所特有的集中化,数据团队往往会因分散在企业中的不同工具和数据孤岛而自然而然地产生分歧。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

07 DataOps 复杂性——测试数据管理

为了创建用于分析的开发环境,您必须创建数据工厂的副本。这需要数据专业人员复制可能具有安全性、治理或许可限制的数据。复制整个数据集可能不切实际或成本高昂,因此需要一些思考和谨慎来构建具有代表性的数据集。对多 TB 数据集进行采样或过滤后,可能必须对其进行清理或编辑(删除敏感信息)。数据还需要基础设施,由于技术障碍或许可证限制,这些基础设施可能不容易复制。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

测试数据管理的概念是 DataOps 中的首要问题,而在大多数 DevOps 环境中,这是事后才想到的。为了加速分析开发,DataOps 必须使用所需的数据、软件、硬件和库自动创建开发环境,以便创新与敏捷迭代保持同步。

08 DataOps 以两种方式连接组织

DevOps 致力于帮助开发和运营(信息技术)团队以集成的方式协同工作。在 DataOps 中,这个概念如图 11 所示。开发团队是分析师、科学家、工程师、架构师和其他创建数据仓库和分析的人。

在数据分析中,运营团队支持和监控数据管道。这可以是 IT,但也包括客户——创建和使用分析的用户。DataOps 将这些团队聚集在一起,以便他们可以更紧密地合作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

自由与中心化

DataOps 还将组织在另一个维度上结合在一起。大量数据分析开发发生在企业的偏远角落,靠近业务部门,使用 Tableau、Alteryx 或 Excel 等自助服务工具。这些从事去中心化、分布式分析创建的本地团队在向用户提供创新方面发挥着至关重要的作用。赋予这些创造力口袋以保持企业的竞争力,但坦率地说,缺乏自上而下的控制会导致无法管理的混乱。

在一组(例如 IT)的控制下集中分析开发,使组织能够标准化指标、控制数据质量、实施安全和治理,并消除数据孤岛。问题是过多的中心化会扼杀创造力。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

DataOps 的一个重要优势是它能够协调数据分析的分散式和集中式开发之间的来回——两者之间的紧张关系集权与自由. 在 DataOps 企业中,新的分析在本地创新领域产生并经过改进。当一个想法被证明有用或值得更广泛地分发时,它会被提升为一个集中的开发团队,他们可以更有效、更稳健地大规模实施它。

DataOps 将本地化和集中式开发结合在一起,使组织能够在保持本地化开发的同时获得集中化的效率——创新矛的尖端。DataOps 将企业跨两个维度整合在一起,如图 13 所示——开发/运营以及分布式/集中式开发。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

DataOps 在组织中的核心团队之间带来了三个创新周期:集中的生产团队、集中的数据工程/分析/科学/治理开发团队,以及使用自助服务工具的团队,这些团队分布在离客户最近的业务线中。图 14 显示了创新的连锁循环。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

09 企业示例:数据分析生命周期复杂性

在高层次研究了 DataOps 开发过程之后,让我们来看看企业环境中的开发生命周期。图 14 说明了从开始到生产的分析过程的复杂性。分析首先由个人创建和开发,然后合并到团队项目中。完成单验收测试后(UAT),分析进入生产。DataOps 的目标是在个人开发环境中创建分析,进入生产环境,接收用户的反馈,然后通过进一步的迭代不断改进。由于人员、工具、代码、版本、手动程序/自动化、硬件、操作系统/库和目标数据的差异,这可能具有挑战性。图 14 中的列显示了这四种环境中每一种环境的不同特征。

如果没有 DataOps,在这四个完全不同的环境中将分析推向生产环境的挑战是艰巨的。它需要拼凑起来的手动操作和脚本,这些脚本本身管理起来很复杂。人工流程容易出错,因此数据专业人员通过长时间工作来弥补,错误地依赖希望和英雄主义来取得成功。所有这些都会导致不必要的复杂性、混乱和大量时间和精力的浪费。图15 所示的生命周期进展缓慢,再加上高严重性错误进入生产环境,可能会使数据分析团队几乎没有时间进行创新。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

写在最后的话

DataOps 简化了数据分析创建和操作的复杂性。它将数据分析开发与用户优先级保持一致。它简化并自动化了分析开发生命周期——从沙箱的创建到部署。DataOps 控制和监控数据工厂,因此数据质量保持高水平,使数据团队专注于增加价值。

您可以通过执行这七个步骤来开始使用 DataOps 。您还可以采用DataOps 平台,该平台将在现有工具和基础架构的上下文中支持 DataOps 方法。

DataOps 平台可自动执行构成 DataOps 的步骤和流程:沙盒管理、编排、监控、测试、部署、数据工厂、仪表板、敏捷等。DataOps 平台专为数据专业人员而构建,旨在将他们所需的所有工具、步骤和流程简化为易于使用、可配置的端到端系统。这种高度自动化消除了大量的手动工作,使团队腾出时间来创建新的创新分析,从而最大限度地提高组织数据的价值。

 


作者:DataKitchen

文章来源:DataOps 不仅仅是数据的 DevOps! (uml.org.cn)

DevOps有什么特征

DevOps是一系列软件开发实践,强调开发人员(Dev)和运维人员(Ops)之间的沟通合作,通过自动化流程,使得软件构建、测试、发布更加快捷、频繁和可靠。

1. DevOps强调一种文化

在很多企业中,开发和运维人员通常隶属于不同部门,有着不同的工作环境,采用不同的沟通方式,使用不同的开发或运维工具,并且有着不同的业务目标,这使得他们之间形成一道参不透的墙。

 Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

DevOps实际是一种文化上的变迁,强调开发、运维、测试等环节之间的沟通合作。意在帮助这些人向着一个共同的目标努力:尽可能为公司提供更多价值。为了支持这种合作的发生,需要在团队内部文化和企业组织文化两个层面做出努力。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2. DevOps是一种实践

所谓DevOps,就是将敏捷方法延伸到Production!

DevOps主要是为了将敏捷开发实践扩展到运维阶段,进一步完善软件构建、验证、部署、交付等流程,使得跨职能团队能够完成从设计到生产支持等各环节的工作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

3. DevOps包含一系列工具链

DevOps是一种融合了一系列基本原则和实践的方法论,并从这些实践中派生出了各种工具。这些工具体现在软件开发和交付过程的不同阶段:

编码:代码开发和审阅,版本控制工具、代码合并工具

构建:持续集成工具、构建状态统计工具

测试:通过测试和结果确定绩效的工具

打包:成品仓库、应用程序部署前暂存

发布:变更管理、发布审批、发布自动化

配置:基础架构配置和部署,基础架构即代码工具

监视:应用程序性能监视、最终用户体验

DevOps对测试提出了哪些挑战

刚参加工作时,我参与了某Audi系汽车电子的软件研发,采用的是传统瀑布开发模式。在整个项目生命周期中,前半部分设计和编码,后半部分用来测试。然而我在东家工作了两年,也没能等到产品交付到用户手上。直到去年,我们的软件才得以量产并投入市场。在这4年中,产品从未交到用户手上,因此无法验证它所带来的价值,也没有任何机会得到用户反馈从而适应变化。

后来,我又参与一个银行项目,我们采用敏捷的开发模式,全功能团队,开发测试并行,每2-3周就交付一个版本。但因为没有真正发布到生产环境,我们仍然无法及时得到有效的用户反馈。

现在,我们采用DevOps的优秀实践,开发和运维协同工作。每个迭代完成,或者每修复一个线上缺陷就立即部署到生产环境。这样,我们就能够迅速从用户处获得反馈并且快速做出响应。

通过参与传统、敏捷和DevOps的项目,我深深地感受到流程的改进对团队以及项目的产出和质量所带来的改变。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

那么,这些改变究竟是对测试提出了什么样的挑战? 我认为有以下几点:

1. 频繁部署

在采用DevOps之后,我们能够根据项目具体情况做到每天甚至一天多次部署。在生产环境频繁部署软件,最大的挑战就是测试。以前,测试基本上都在开发阶段之后和产品上线之前完成。但现在,不再有充足的时间留给QA团队去发现问题再抛给开发团队来修复。那么,速度成了测试面临的一大挑战。

2. 自动化

DevOps强调将流程自动化,测试作为其中一个重要环节,势必要大规模实现自动化。因此测试人员的自动化编码能力正在面临极大的挑战。

3. 实践和反馈

敏捷提倡我们要拥抱变化,更多的是要适应需求的不断变化。虽然一部分功能性需求是明确又具体的,我们清楚的知道用户想要什么,也因此易于测试。然而,也有一些非功能性需求的验收标准没那么明确,比如:提高应用性能达到良好的用户体验。我们如何才能验证用户体验是否真的良好呢?仅仅通过性能指标吗?当然不是,满足指标只能说明一部分问题,唯有真实的用户数据和反馈才是可最靠的。

4. 协作

敏捷强调全功能开发团队的共同协作,但这仅仅止于开发阶段。而DevOps注重Dev、Ops和QA三个群体之间的密切协作。因此,良好的角色定位能够帮助测试人员将价值最大化。

我们是如何做测试的

Laurent曾经在Hiptest上发表了博客《Shift left and shift right: the testing Swing》,提出了一个有意思的测试矩阵,从四个维度进行分析,描述了当软件开发模式从瀑布到敏捷、再到DevOps转型时,测试该如何响应变化。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Laurent提出一个测试左移和右移的概念:

测试左移,就是指在开发阶段之前定义测试。

测试右移,就是直接在生产环境中监控,并且实时获取用户反馈。

在敏捷开发的生命周期中,我们通过每一次迭代来丰富和更新产品,以使其最大限度地符合客户对系统的需求。当时测试的关注点基本停留在开发阶段,以保证产品达到上线标准。引入DevOps之后,我们不仅要关注产品的质量是否达标,还需要使价值假设得到及时的验证。因此,我们不仅要将测试左移,在开发环境验证功能的可用性,还要进行测试右移,通过监控产品在生产环境的运作情况,来验证其价值并获得反馈,从而持续改进。基于这些理解,我在项目上做了初步的尝试并取得良好的效果。我将这些尝试和实践总结为以下几点:

1.如何保证新功能得以实现?

在开发环境,我们开发新功能,并且通过测试保证其达到产品验收标准。

首先,使用BDD(Behavior Driven Development,BDD)的方式定义用户需求,这样用特定的语言来描述用户行为,能够使各个角色(测试、开发、产品负责人、市场等)对业务价值达成一致的理解,从而使其从需求到最后的测试验证,进行高度的协作和沟通,最后交付最有价值的功能。同时,QA能够提前Review故事卡,补充验收标准。除此之外,BDD方式的用户需求可以直接指导测试,后续我会写到。

其次,采用单测试来验证最基本的代码逻辑。在编写单测试时,建议Dev和QA Pair工作。单测试可以认为是编码的一部分,要对系统的代码逻辑有深入的了解,因此,Dev是最合适的人选,而QA可以帮助测试覆盖的更全面。

最后,每一个功能都要严格按照故事卡的AC(Acceptance Criteria)进行验收,并采用探索性测试方法来对新功能进行无死角测试。

2.怎样验证新功能的价值?

我们将新功能部署到生产环境以后,接下来就应该衡量业务价值是否达到预期。

验证预期的一个好方法是衡量用户的行为变化。比如:在上传图片的功能后面添加了一个预览按钮,但用户却极少用它,很可能是因为用户根本不需要这个按钮,或者按钮放在了不恰当的位置导致用户不方便使用,亦或是按钮样式不够友好,导致用户没有欲望使用它。这时候,该按钮的业务价值就没有真正达到,是时候调整一下了。

3.如何确保已有功能不被破坏?

在软件开发中,任何代码都不可能完全独立存在,一行代码的变更也有可能导致系统的全面崩溃。那么,如何保证在开发新功能的同时,已有功能不被破坏?换句话说,如何做到全面的回归测试?人力是最高成本,也有现实的局限性,比如,人手不够,重复做同样的事情人会变得烦躁,手不够快导致效率低下等。因此,自动化测试才是不二选择。

将BDD需求直接转化为自动化测试用例。每个测试用例都应该讲一个关于应用程序的故事。当一个测试用例使用一致的业务术语定义时,它的可读性会比较高,且容易自动化。与此同时,上一个迭代的用例在下一个迭代就可以迅速转化为回归测试的基线。

支持BDD的工具有很多,比如:Cucumber。简单举个例子,如图:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

BA用BDD方式定义用户需求,QA Review并补充AC,然后将其编写为自动化测试脚本。如果QA的编码能力较弱,可以让Dev协助完成代码实现的部分。这也充分说明了协作的意义。

最后,也是更重要的部分,测试应该集成在CI中。每一次Build或者每天都要去执行测试,验证已有功能是否完好。这样才会对没有预期到的变化产生的问题给出快速反馈。

另外,做一些性能测试、兼容性测试、和安全性测试等等。

4.怎样验证产品的可靠性?

有时候,某些缺陷并不是源于代码的错误,而是一个不好的用户体验,或者只有当数据达到一定量时才会出现,测试人员是无法模拟这种类型的测试的,因此直接在生产环境监控变得高效又可靠。通常我们需要监控两种特性:性能和可用性。

使用工具持续获取用户数据,或者使用log持续获取性能信息。这有助于监控产品部署到生产环境后是如何正确运作的。快速启用一个功能,在生产环境实时监控验证其业务价值,获取到有效且快速的用户反馈,加之拥有持续部署的能力,我们能够在出现问题的时候快速做出反应,从而使得我们的产品更加可靠。

这里实际上融入了《QA in Production》的理念。现如今,已经有很多工具和方法支持在生产环境做测试了。篇幅太长,这里就不做详细阐述了,请参考原文。

到这里,再来回顾一下,我们的实践是否真的卓有成效。

用BDD的方式定义用户需求、编写测试,有益于不同角色之间的一致理解和共同协作。

自动化测试解决了频繁部署所带来的挑战,同时保证产品的整体功能持续得到回归和验证。

在线监控能有效地验证不确定需求,通过生产数据分析和预警问题的发生,并且快速获取用户反馈从而及时调整。除此之外,这一点也充分体现了Dev、QA和Ops的协作,像监控等原本只能Ops做的事,现在Dev或QA一样可以做。

写在最后

测试是一种活动,曾经我们通过它来验证产品是否达到上线标准。现在DevOps模式下,我们需要在各个阶段不断地执行测试活动,以达到产品质量的持续改进。

而QA(Tester)仅仅是一种较多进行测试活动的角色。敏捷一直强调“团队为质量负责”,测试不再是QA(Tester)的专属。DevOps模式更是对测试、尤其是自动化测试提出了更高的要求,也对QA的编码能力提出了极大的挑战。作为团队成员,每个人都有责任了解开发流程、提高测试技能,把好测试这一关。但是,测试活动作为QA(Tester)的主要职责之一,提高自动化测试技能,就是当下每个QA(Tester)最为紧急且重要的事情了。



作者:京东物流 冯鸿儒

1 简介

Gossip是一种p2p的分布式协议。它的核心是在去中心化结构下,通过将信息部分传递,达到全集群的状态信息传播,传播的时间收敛在O(Log(N))以内,其中N是节点的数量。基于gossip协议,可以构建出状态一致的各种解决方案。
一些常见的分布式协议如二阶段提交协议和 Raft 算法,你发现它们都需要全部节点或者大多数节点正常运行,才能稳定运行。而Gossip即使只有一个节点可用也能提供服务。

1.1 适用场景

适用于AP 场景的数据一致性处理:分布式数据库中节点同步数据使用(如Apache Cassandra、Redis Cluster);
其他场景如信息扩散、集群成员身份确认、故障探测等(如Consul)。

1.2 优势

  • 学习成本:实现简单
  • 扩展性:允许节点的任意增加和减少,新增节点的状态 最终会与其他节点一致。
  • 容错:任意节点的宕机和重启都不会影响 Gossip 消息的传播,具有天然的分布式系统容错特性。可以在一定程度上避免网络分割带来的问题。
  • 去中心化:无需中心节点,所有节点都是对等的,任意节点无需知道整个网络状况,只要网络连通,任意节点可把消息散播到全网。
  • 性能:指数级一致性收敛。消息会以“一传十的指数级速度”在网络中传播,因此系统状态的不一致可以在很快的时间内收敛到一致。消息传播速度达到了 logN。
    Gossip协议的最大的好处是,即使集群节点的数量增加,每个节点的负载也不会增加很多,几乎是恒定的。如Consul管理的集群规模能横向扩展到数千个节点。

1.3 劣势

  • 消息延迟:节点随机向少数几个节点发送消息,消息最终是通过多个轮次的散播而到达全网;不可避免的造成消息延迟。
  • 消息冗余:节点定期随机选择周围节点发送消息,而收到消息的节点也会重复该步骤;不可避免的引起同一节点消息多次接收,增加消息处理压力。

2 细节介绍

2.1 传播方式

Gossip 协议的消息传播方式主要有两种:Anti-Entropy(反熵传播)和 Rumor-Mongering(谣言传播)。

2.1.1 反熵传播

  • 定义:反熵(指消除不同节点中数据的差异,提升节点间数据的相似度,降低熵值)。反熵传播:以固定的概率传播所有的数据,可用来避免因为UDP数据包丢失或者新节点的加入而导致的集群数据不一致问题。
  • 过程:集群中的节点,每隔段时间就随机选择某个其他节点,然后通过互相交换自己的所有数据来消除两者之间的差异,实现数据的最终一致性。
  • 适用场景:执行反熵时,相关的节点都是已知的,而且节点数量不能太多,如果是一个动态变化或节点数比较多的分布式环境(比如在 DevOps 环境中检测节点故障,并动态维护集群节点状态),这时反熵就不适用了。
  • 缺点:消息数量非常庞大,且无限制;通常只用于新加入节点的数据初始化。可以通过引入校验和(Checksum)等机制,降低需要对比的数据量和通讯消息等。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.1.2 谣言传播

  • 定义:当一个节点有了新数据后,这个节点变成活跃状态,并周期性地联系其他节点向其发送新数据,直到所有的节点都存储了该新数据。
  • 过程:消息只包含最新 update,谣言消息在某个时间点之后会被标记为 removed,并且不再被传播。
  • 当一个新节点A连接到Gossip集群内的某个节点B时,A节点会将自己的信息发送给B节点,然后B节点会在集群中随机选取几个未被传染的节点,向他们广播A节点的信息(首次传染),集群中的其他节点收到A节点的信息后,又会像B节点那样广播A节点的信息给其他未被传染的节点(二次传染)。直至多次传染后,集群所有节点都收到了A节点的信息,同步完成。
  • 适用场景:适合动态变化的分布式系统。
  • 缺点:系统有一定的概率会不一致,通常用于节点间数据增量同步。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.2 通信方式

Gossip 协议最终目的是将数据分发到网络中的每一个节点。根据不同的具体应用场景,网络中两个节点之间存在三种通信方式:推送模式、拉取模式、Push/Pull。

  • Push: 节点 A 将数据 (key,value,version) 及对应的版本号推送给 B 节点,B 节点更新 A 中比自己新的数据
  • Pull:A 仅将数据 key, version 推送给 B,B 将本地比 A 新的数据(Key, value, version)推送给 A,A 更新本地
  • Push/Pull:与 Pull 类似,只是多了一步,A 再将本地比 B 新的数据推送给 B,B 则更新本地

如果把两个节点数据同步一次定义为一个周期,则在一个周期内,Push 需通信 1 次,Pull 需 2 次,Push/Pull 则需 3 次。虽然消息数增加了,但从效果上来讲,Push/Pull 最好,理论上一个周期内可以使两个节点完全一致。直观上,Push/Pull 的收敛速度也是最快的。

2.3 执行示例

2.3.1 状态的传播

以Gossip协议同步状态的思路类似于流言的传播,如下图所示。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

A节点率先知道了某个流言(msg),它首先将此信息传播到集群中的部分节点(比如相邻的两个节点)B和C,后者再将其传递到它们所选择的“部分”节点,例如B选择了D和E,C选择了将流言传播到B和F。以此类推,最终来自于A的这条流言在3轮交互后被传播到了集群中的所有节点。
在分布式系统的实践中,这个“流言”可能是:某个节点所感知到的关于其它节点是否宕机的认识;也可能是数据水平拆分的缓存集群中,关于哪些hash桶分布在哪些节点上的信息。每个节点起初只掌握部分状态信息,不断地从其它节点收到gossip信息,每个节点逐渐地掌握到了整个集群的状态信息。因此解决了状态同步的第一个问题:全集状态的获取。
对于集群中出现的部分网络分割,消息也能通过别的路径传播到整个集群。如下图所示:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.3.2 状态的一致

状态同步的第二个问题:对于同一条状态信息,不同的节点可能掌握的值不同,也能通过基于gossip通信思路构建的协议包版本得到解决。例如水平拆分的redis缓存集群,初始状态下hash桶在各个节点的分布如下图所示:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

此时各个节点预先通过某种协议(比如Gossip)得知了集群的状态全集,此时新加入了节点D,如下图所示:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

D分担了C的某个hash桶,此时C/D和集群中其它节点就C所拥有哪些hash这件事发生了分歧:A/B认为C目前有6/7/8个hash桶。此时通过为gossip消息体引入版本号,使得关于C的最新状态信息(只有6/7两个桶了)在全集群达到一致。例如B收到来自A和C的gossip消息时会将版本号更新的消息(来自C的v2)更新到自己的本地副本中。
各个节点的本地副本保存的集群全量状态也可能用来表示各个节点的存活状态。对于部分网络分割的情况如下图所示:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

例如A和C的网络断开,但A和C本身都正常运行,此时A和C互相无法通信,C会将A标记为不可用状态。对于中心化思路的协议,如果C恰好是中心节点,那么A不可用的信息将会同步到集群的所有节点上,使得这些节点将其实可用的A也标记为宕机。而基于gossip这类去中心化的协议进行接收到消息后的实现逻辑扩展(例如只有当接收到大多数的节点关于A已经宕机的消息时,才更新A的状态),最终保证A不被误判为宕机。

3 开源软件中的应用

3.1 Fabric

Fabric gossip使用push(从成员视图随机选出活跃邻居,给他们转发消息),pull(定期探测,请求遗失的消息)的方式扩散区块。

3.2 Cassandra

Cassandra使用的是pull-push,这种方式是均等的,会有3次发送,但是发送完以后双方都可以更新彼此的信息。利用pull-push方式,如果A要与B节点同步,需要进行如下图的三个通信阶段。

3.3 RedisCluster

Redis Cluster 在运行时,每个实例上都会保存 Slot 和实例的对应关系(也就是 Slot 映射表),以及自身的状态信息。新节点加入、节点故障、Slot 变更等事件发生时,实例间也可以通过 gossip协议进行PING、PONG 消息的传递,完成集群状态在每个实例上的同步。
redisCluster默认组建集群的方式:

  • 通过cluster meet命令将一个节点跟集群中其中一个节点建立连接(此时只能被集群中这一个节点认识)
  • 通过Gossip消息转播给其他节点,其他节点收到消息后,再通过类似meet的命令来跟对新节点建立集群连接(需要一定时间的扩散)

使用gossip算法利用PFAIL和FAIL flags的转换和传播来判定故障

3.4 Consul

一致性协议采用 Raft 算法,用来保证服务的高可用.
成员管理和消息广播 采用GOSSIP协议,支持ACL访问控制。
consul是建立在serf之上的,它提供了一个完整的gossip协议,用在很多地方。Serf提供了成员,故障检测和事件广播。Gossip的节点到节点之间的通信使用了UDP协议。
Consul的每个Agent会利用Gossip协议互相检查在线状态,本质上是节点之间互Ping,分担了服务器节点的心跳压力。如果有节点掉线,不用服务器节点检查,其他普通节点会发现,然后用Gossip广播给整个集群。

4 总结

gossip协议是很多开源中间件和区块链实现的一种底层通信机制,掌握它的原理和细节能更好的理解中间件和区块链的一些行为和分布式特性。


点亮 ⭐️ Star · 照亮开源之路

https://github.com/apache/dolphinscheduler

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

//

每个人对于”开源社区“的定义都不一样,在社区的想法也完全不一样,我认为玩开源就像”谈恋爱“,要想方设法对它好,在接触 Apache DolphinScheduler 社区之后,我从”非技术“的视角真真实实地感受到了 Apache Way 。

因为你在非技术的角度会发现,很多时候,并不是”大佬“没技术,而是缺乏发掘、激励”大佬“的人,这里指的并不是物质上的奖励,归属感是最重要的原因,哪怕你跟社区的用户1V1打个电话,都能给他找到归属感。

01 个人简介

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

曾辉 白鲸开源 高级社区经理

GitHub:https://github.com/Niko-Zeng

2年开源社区运营经验,目前专注大数据调度、数据集成等开源社区布道推广,致力于传播开源文化,打造社区生态。

02 对社区的主要贡献

我主要在社区负责 Apache DolphinScheduler 全球运营工作,提升“小海豚”在全球的影响力及社区内部的建设。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

有的人把开源项目比喻成“大树”,把开源比喻成“土壤”,而我就只有一个想法:“千方百计让它好”,我觉得运营社区跟“谈恋爱”是一样的,当然我们跟”舔狗“要做区分,因为运营的事情太杂了,甚至你在下班时间还得处理社区的事情,如果你不把社区当“对象”,是很难适应的。

从加入社区以来,我会自主发起并组织一些社区内的活动,比如在中国区由我组织的 Meetup 已经有10多场,平均下来每个月有一场,其中还包括推荐社区去参加“大数据”领域的技术活动分享,值得一提的是,除了组织活动这个工作流之外,我还几乎搜集了所有国内“大数据”领域的开源项目,并利用这个 list ,逐个去拜访交流,我深以为一个优秀的项目一定是需要有良好的生态,需要走出去跟更多的优秀的社区形成交流和合作,这其中的给社区带来的好处,大家在平时的活动中也应该能感受到!

同理,我在海外的拓展也进行“如法炮制”,但是由于国家文化习惯和语言的差异,对于我而言,困难还是巨大的,其背后花费的精力也是难以想象的。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

跟来自美国、欧洲、印度、新加坡等地区的 Jupyter、Beam 社区的朋友洽谈相关合作。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

截止目前,我们在海外已经成功举办3场Meetup,在美国、印度、新加坡、德国、法国、芬兰等地成功举办线上Meetup。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我在想与其说介绍贡献,倒不如用个称呼来形容我的角色,我更像一个“辅助”,能抗能打能奶,能号召更多人,协调更多人,发现更多人,挖掘更多人,我认为这也是“Apache way”在我心中的解读和实践。

的确,我现在挺享受在开源社区做运营这份工作,从加入社区到现在,甚至有时候恨不得自己能参与“Coding”,这样不仅能在社区“如鱼得水”,甚至在外部交流也能跟其他大数据工程师侃侃而谈。

其他的贡献更像一个“文档”整理者的角色,知识的搬运工,经过我整理的活动文章、技术投稿还有长短视频,在全网阅读量已经超过了10W+。

03 与 DolphinScheduler 结缘

我最开始接触开源的经历是在开放原子开源基金会,那个时候担任开源教育运营经理,作为国内首个开源基金会,运营的项目特别多,其中比较有代表性的有 OpenHarmony 项目,后面由于工作的变动就加入了 DolphinScheduler 社区,社区给我的感觉是真的非常活跃,里面真的藏龙卧虎,尤其是我有一些给社区布道的需求,需要社区给予我“子弹”的时候,有很多兄弟响应和支持我,在这里,也非常感谢社区的“大佬”们指导,希望在后面能够跟大家一起把海豚调度做成全世界有影响力的调度器。

04 社区的初印象

从非技术的角度来说,总是能第一时间听到社区的声音“又发现BUG了、问题没人及时回答”等等,后面我才知道,这些声音对于开源社区来说,都是一些好的信号,大家能一起发现BUG,一起提PR,一起修复BUG,甚至在社区能一起相互答疑!

唉,这里可能有兄弟说“群里很多问题还是没人回答”,在这里我也呼吁下大家,开源社区里面的用户是没有责任给其他人回答问题的,唯一的办法就是_“如果你觉得没有果子摘,先看看你有没有种过树”_,需要所有人来维护这个氛围,从我的角度,甚至恨不得自己能懂技术、懂开发来帮忙答疑。

但是我心里很清楚,这是没办法从根本上解决问题,在这里向“社区自发当客服的用户”表示崇高的敬意,其中还包括海豚调度社区中国区第一任管理员们,他们分别是晏江、许志武、张琦琛、王昱翔、向梓豪、杨启煜、杨佳豪、高楚枫、高枫;

(排名不分先后,按照7-15群管理员排序)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如果非要“吐槽”,那就是大家真的都好忙啊,有时候我都不太好意思去 Ping 大佬们,当然,这也让我联想到目前中国开发者的现状,大家普遍时间非常紧,能干完自己的事情,再来干开源的兄弟,我个人是致以最高的敬意🙋‍♂️。

05 社区留言板

看到这里,不知道你心里是不是也想通过非代码贡献成为 Committer ,如果你没有时间参与代码贡献,欢迎找我聊聊参与非代码贡献包括但不限于:社区分享(中英文)、文章投稿、全球活动组织、文档修复、反馈问题、闲聊DS社区发展的建议。

06 获推选 Commiter 感言

很感谢社区对我的认可!同时也感谢社区小伙伴带我更清晰的认识 Apache Way,以及在我提出想法、问题时给予的支持。

Apache DolphinScheduler 目前也处于全球化的关键节点,面临着很多挑战,希望能和社区小伙伴们一起共同努力,把“小海豚”打造成世界一流的调度工具,同时也祝愿社区里面的兄弟能在社区收获自己想要的技术成果,就像社区的Slogan“调度选得好,下班回家早; 调度用得对,半夜安心睡”

致 谢

感谢一路支持和指导我的社区大佬们,有些人甚至在深夜跟我通话长达1个小时,只为讨论 DS 如何前进!有些人辗转反侧为我对接资源,有些人奋力为社区布道做出自己的努力…..

王昱翔、高楚枫、陈卫、单葛尧、柏雪松、徐海辉、张柏强、董文彬、卢栋、钟霈合、徐帅、许名勇、李岗、郭书培、姜涛、郑平贺、孔帅、邓子琦、李建军、晏江、杨启煜、张琦琛、向梓豪、杨佳豪、高枫、许志武、钟嘉杰、张睿、邹先生、龙旺、岳贤昌、申凯、陈卓宇、陈家名、进豪、杨林伟、淡先生、马鹏飞等

海外推动DS社区:Shardingspere社区Yacine、Trino 社区 Advocate Brian、ALC Indore 小姐姐 Priya、Jupyter社区 Isabela等

从某个层面来说,能赋能社区真的是一件很 Cool 的事情,有太多太多的回忆,如果有遗漏的致谢,希望见谅,因为社区实在人太多了哈哈哈哈!

参与贡献

随着国内开源的迅猛崛起,Apache DolphinScheduler 社区迎来蓬勃发展,为了做更好用、易用的调度,真诚欢迎热爱开源的伙伴加入到开源社区中来,为中国开源崛起献上一份自己的力量,让本土开源走向全球。

参与 DolphinScheduler 社区有非常多的参与贡献的方式,包括:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

贡献第一个PR(文档、代码) 我们也希望是简单的,第一个PR用于熟悉提交的流程和社区协作以及感受社区的友好度。

社区汇总了以下适合新手的问题列表:https://github.com/apache/dolphinscheduler/issues/5689

非新手问题列表:https://github.com/apache/dolphinscheduler/issues?q=is%3Aopen+is%3Aissue+label%3A%22volunteer+wanted%22

如何参与贡献链接:https://dolphinscheduler.apache.org/zh-cn/community/development/contribute.html

来吧,DolphinScheduler开源社区需要您的参与,为中国开源崛起添砖加瓦吧,哪怕只是小小的一块瓦,汇聚起来的力量也是巨大的。

参与开源可以近距离与各路高手切磋,迅速提升自己的技能,如果您想参与贡献,我们有个贡献者种子孵化群,可以添加社区小助手(Leonard-ds) ,手把手教会您( 贡献者不分水平高低,有问必答,关键是有一颗愿意贡献的心 )。

添加小助手时请说明想参与贡献,开源社区非常期待您的参与。

作者:京东科技 贾世闻

最近想看看 rust 如何集成 clickhouse,又犯了好吃懒做的心理(不想自己建环境),刚好我东发布了兼容ck 的云原生数仓 Starwfit,于是搞了个实例折腾一番,看看 rust 如何与 starwift 打交道。

创建集群

  • 登录控制台,直接选配创建即可

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 创建用户

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

  • 开启白名单

为了保证starwift能够被外部资源访问需要开启白名单,默认情况下新创建的实例只有该实例所在vpc下才能访问

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

为了方便,实验环境直接编辑 default 分组,编辑 ip 列表为 0.0.0.0/0,对所有ip开放。在实际生产环境需要根据实际情况配置白名单避免安全问题。

  • 开启公网连接

为了实验方便,开启公网访问域名便于开发和测试

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

mac客户端安装

  • 安装客户端

    macos 客户端安装

    
    

    其他客户端安装 参见 clickhosue 官方文档

  • 测试连通性

    
    
    
    

rust 连接 starwift

starwift 支持 tcp 和 http 两种协议连接server。下面我们分别给出两种方式的示例代码

  • tcp 连接

    • 依赖 crate

      
      
    • 示例代码

      
      
  • http 连接

    • 依赖 crate

      
      
    • 示例代码

      
      

测试过程中,遇到了依赖冲突问题,clickhouse-rs 和 clickhouse.rs 同时依赖了 clickhouse-rs-cityhash-sys 但依赖方式不同,导致编译不通过,下一期详细聊聊踩坑及爬坑过程。 再次感谢京东云数据库团队提供的 starwift 测试实例。 下期见。

作者:京东科技 赵龙波

“贾维斯,你在吗?”

“随时待命,先生。”

类似《钢铁侠》里的人工智能助理贾维斯,ChatGPT或许是你的随时待命的助手。ChatGPT在大量文本数据上进行了培训,这使它能够理解单词和短语的上下文和含义,并生成高度相关的上下文响应。能完成撰写邮件、视频脚本、文案、翻译、代码等任务,作为一名开发人员,尝试探索一下chatGpt对我们的工作能有哪些帮助。 (由于 ChatGPT对国内禁止访问,以下是通过调用openAI的api接口实现的对话,所以界面与原生有所不同。网上很多种实现方式,不多赘述。)

先来看看chatGPT自己的回答:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

每次回答都不一样,但都差不多的意思,这个回答比较抽象,如果再具体一些就好了。下面列出了一些使用场景:

回答一些基础的编程或者计算机问题

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这应该对AI来说是小儿科了,但确是比较常用的功能,不懂就问。

生成正则表达式

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这两个答案都是准确的。这样使用起来确实比搜索要方便很多

编写脚本

如:shell脚本

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这个脚本是正确的,再来一个复杂的:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

为了验证这个脚本是否正确,去服务器上运行了一下,是没有问题的,并且nginx路径就是nginx默认的文件夹路径,不用更改: Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

写sql语句也不在话下:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

我这里问的比较口语化,且写错了标点符号,它还是理解了。

shell脚本可能是AI使用它海量内容查询到类似的然后仿造的,但sql语句是它真的理解了问题并结合实际语法创造出来的👍。

文字命名格式转换:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

文字格式转换有成熟的各种实现,这也算一种途径。

生成代码

比如:写一个简单获取每月最后一天的公共方法

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

上面实现不难,再尝试写一个包含多个方法的工具类,并一次生成

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

不仅给出了代码,还把注释也打上了👍

甚至可以约定使用的java类版本

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

如果你对这个写法不满意,同一个问题再次发问,还能给出其他写法:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

项目中经常用到各种各样的工具类,也许下次试试直接说出你要的功能,让AI给你写出来吧

起名字

如:给某个类命名

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

你正在看的这篇文章标题也是chatGpt起的,这是经常头疼类名应该怎么起的人的福音。

生成伪代码:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

在技术方案设计或者讨论的时候如果需要写一些代码,可以尝试。

代码优化

如:代码bug修复:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

甚至帮你把代码重写

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

依然可以,如果你想把代码用lambda重写,让它来试试。

技术资料翻译:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

这是截取的G1英文文档的一段描述,这里面包含了一些G1垃圾回收器的参数信息,翻译时这些应该保留为英文,新生代和老年代这些特有名词也最好用英文表示才更专业,这些细节它都做到了,且它的翻译与中文版本的差别不大,几乎没有错误。

其他功能

如: 算法实现:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

以上测试数据都比较偏简单,但依然能看出它的潜力。纯业务场景代码需要结合实际项目,相信如果让它学习训练某一个项目之后,或者他真的可以写出一些业务功能的代码来。google等一系公司也在研究AI编程可能行,足以说明其潜力。

可以在idea里安装NexChatGPT插件,方便随时调用查询。 如果有更好的使用场景idea,欢迎留言讨论。

ps,最后一问:

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

作者:京东物流 刘作龙

前言:
学习底层原理有的时候不一定你是要用到他,而是学习他的设计思想和思路。再或者,当你在日常工作中遇到棘手的问题时候,可以多一条解决问题的方式

分享大纲:
本次分享主要由io与nio读取文件速度差异的情况,去了解nio为什么读取大文件的时候效率较高,查看nio是如何使用直接内存的,再深入到如何使用直接内存

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

1 nio与io读写文件的效率比对

首先上代码,有兴趣的同学可以将代码拿下来进行调试查看


1.主函数调用
为排除当前环境不同导致的文件读写效率不同问题,使用多线程分别调用io方法和nio方法

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

2.分别进行IO调用和NIO调用
通过nio和io的读取写入文件方式进行操作

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

3.结果
经过多次测试后,发现nio读取文件的效率是高于io的,尤其是读取大文件的时候


4 提出疑问
那到底为什么nio的速度要快于普通的io呢,结合源码查看以及网上的资料,核心原因是:
nio读取文件的时候,使用直接内存进行读取,那么,如果在nio中也不使用直接内存的话,会是什么情况呢?

5.再次验证
新增使用堆内存读取文件

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

执行时间验证如下:


根据上述的实际验证,nio读写文件比较快的主要原因还是在于使用了直接内存,那么为什么会出现这种情况呢?

2 直接内存的读写性能强的原理

直接上图说明
1.堆内存读写文件

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

堆内存读写文件的步骤:
当JVM想要去和磁盘进行交互的时候,因为JVM和操作系统之间存在读写屏障,所以在进行数据交互的时候需要进行频繁的复制

  • 先由操作系统进行磁盘的读取,将读取数据放入系统内存缓冲区中
  • JVM与系统内存缓冲区进行数据拷贝
  • 应用程序再到JVM的堆内存空间中进行数据的获取

2.直接内存读写文件

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

直接内存读写文件的步骤
如果使用直接内存进行文件读取的时候,步骤如下

  • 会直接调用native方法allocateMemory进行直接内存的分配
  • 操作系统将文件读取到这部分的直接内存中
  • 应用程序可以通过JVM堆空间的DirectByteBuffer进行读取
    与使用对堆内存读写文件的步骤相比减少了数据拷贝的过程,避免了不必要的性能开销,因此NIO中使用了直接内存,对于性能提升很多

那么,直接内存的使用方式是什么样的呢?

3 nio使用直接内存的源码解读

在阅读源码之前呢,我们首先对于两个知识进行补充

1.虚引用Cleaner sun.misc.Cleaner

什么是虚引用
虚引用所引用的对象,永远不会被回收,除非指向这个对象的所有虚引用都调用了clean函数,或者所有这些虚引用都不可达

  • 必须关联一个引用队列

  • Cleaner继承自虚引用PhantomReference,关联引用队列ReferenceQueue

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    概述的说一下,他的作用就是,JVM会将其对应的Cleaner加入到pending-Reference链表中,同时通知ReferenceHandler线程处理,ReferenceHandler收到通知后,会调用Cleaner#clean方法

    2.Unsafesun misc.Unsafe
    位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。

    3.直接内存是如何进行申请的 java.nio.DirectByteBuffer

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    进入到DirectBuffer中进行查看

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    源码解读
    PS:只需要读核心的划红框的位置的源码,其他内容按个人兴趣阅读

    • 直接调用ByteBuffer.allocateDirect方法
    • 声明一个一个DirectByteBuffer对象
    • 在DirectByteBuffer的构造方法中主要进行三个步骤
      步骤1:调用Unsafe的native方法allocateMemory进行缓存空间的申请,获取到的base为内存的地址
      步骤2:设置内存空间需要和步骤1联合进行使用
      步骤3:使用虚引用Cleaner类型,创建一个缓存的释放的虚引用

    直接缓存是如何释放的
    我们前面说的了Cleaner的使用方式,那么cleaner在直接内存的释放中的流程是什么样的呢?

    3.1 新建虚引用

    java.nio.DirectByteBuffer

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    步骤如下

    • 调用Cleaner.create()方法
    • 将当前新建的Cleaner加入到链表中

    3.2 声明清理缓存任务

    查看java.nio.DirectByteBuffer.Deallocator的方法

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    • 实现了Runnable接口
    • run方法中调用了unsafe的native方法freeMemory()进行内存的释放

    3.3 ReferenceHandler进行调用

    首先进入:java.lang.ref.Reference.ReferenceHandler

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    当前线程优先级最高,调用方法tryHandlePending

    进入方法中,会调用c.clean c—>(Cleaner)

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    clean方法为Cleaner中声明的Runnable,调用其run()方法
    Cleaner中的声明:private final Runnable thunk;

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    回到《声明清理缓存任务》这一节,查看Deallocator,使用unsafe的native方法freeMemory进行缓存的释放

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    4 直接内存的使用方式

    直接内存特性

    • nio中比较经常使用,用于数据缓冲区ByteBuffer
    • 因为其不受JVM的垃圾回收管理,故分配和回收的成本较高
    • 使用直接内存的读写性能非常高

    直接内存是否会内存溢出
    直接内存是跟系统内存相关的,如果不做控制的话,走的是当前系统的内存,当然JVM中也可以对其使用的大小进行控制,设置JVM参数-XX:MaxDirectMemorySize=5M,再执行的时候就会出现内存溢出

    Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

    直接内存是否会被JVM的GC影响
    如果在直接内存声明的下面调用System.gc();因为会触发一次FullGC,则对象会被回收,则ReferenceHandler中的会被调用,直接内存会被释放。

    我想使用直接内存,怎么办
    如果你很想使用直接内存,又想让直接内存尽快的释放,是不是我直接调用System.gc();就行?
    答案是不行的

    • 首先调用System.gc();会触发FullGC,造成stop the world,影响系统性能
    • 系统怕有初级研发显式调用System.gc();会配置JVM参数:-XX:+DisableExplicitGC,禁止显式调用

    如果还想调用的话,自己使用Unsafe进行操作,以下为示例代码
    PS:仅为建议,如果没有对于Unsafe有很高的理解,请勿尝试

    
    

    5 总结

    JVM相关知识是中高级研发人员必备的知识,学习他的一些运行原理,对我们的日常工作会有很大的帮助

ChatGPT 已然是 2023 开年至今,互联网上最热的话题没有之一。从去年的 AI 图片生成,到 ChatGPT,再到现在各种基于大模型的应用如雨后春笋般出现……在人们探讨技术无限可能的同时,另一个更深刻的命题也不可回避地浮现出来:

AI 似乎证明了自己有推进生产力变革的能力。那么,谁会是下一个「马车车夫」和「纺织女工」?

深耕互联网多年的知名产品人黄有璨,在自己的公众号里写道,「以前大家一贯认为 AI 会优先取代很多蓝领工种。但万万没想到,当前 GPT 高速进化的背后,实际情况更可能是:一批白领会被优先取代掉。」

假如我们证实了 ChatGPT 可以做翻译、写文案、敲代码、分析数据、总结概要、制作表格……那么,它是威胁还是助力? 又或者,类似 ChatGPT 的能力将多大程度地帮助组织提升工作效率?

作为同样致力于探索 AI 在工作场景中应用的团队,LigaAI 对于 ChatGPT 的能力也有许多好奇:ChatGPT 能多大程度地成为研发团队的帮手?事务性工作之外,它「懂」管理吗?在研发效能等略显含糊的话题上,它会给出怎样的答案?

于是,便有了这次「对话」:LigaAI 与 ChatGPT 的研发效能七连问


开始之前,我们为 ChatGPT 预设了它的角色,以保证其响应内容的范围。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

第一部分:研发效能是什么?

Q1:对敏捷团队而言,研发效能是什么?

ChatGPT: 对于敏捷团队而言,研发效能指的是团队在实现项目目标的同时,以尽可能短的时间和最少的资源,提供高质量的产品。这包括团队成员的效率、代码质量、沟通效率、团队协作效率等。

研发效能是团队不断改进和优化工作流程的结果,它是团队在实现项目目标的同时,不断提高效率和降低成本的能力。

LigaAI 说两句: 第一个问题,我们尝试获得多个不同的回答,却发现 ChatGPT 只是在用不同的方式,将「高质量」「高效率」和「完成项目目标」三个词排列组合。

不得不提的是,基于 GPT-3.5 模型的 ChatGPT 在「内容可读性」上取得了非常大的进步。它能将信息整合成不重复的、阅读通顺的文字和段落,我们甚至很难一眼区分内容是出自人还是机器。

Q2:分别从研发团队和个人的角度,谈谈研发效能的提升如何实现?

ChatGPT: 从研发团队的角度,提升研发效能可以通过以下几个方面实现:

  1. 采用敏捷开发方法:通过短期迭代和反馈循环,提高项目的效率和质量,提升团队协作效率和创新能力.
  2. 精益管理实践:精益管理可以帮助团队识别并去除浪费,提高团队生产力和效率。
  3. 冲突指导:设计有效的冲突解决机制,解决分歧和争议,促进团队协作与创新。
  4. 技术成长:定期安排培训和学习机会,持续精进技术团队的技能和知识,提高团队整体表现和效率。
  5. 研发团队管理:通过清晰的角色定义、责任分配和沟通渠道,管理团队的行动和进度以提高团队效能。

从个人角度看,研发效能的提升可以通过以下方法实现:

  1. 技术提升:不断学习和提高个人技术水平,以提高工作效率。
  2. 任务管理:通过合理的任务管理方法,提高工作效率。
  3. 沟通技巧:通过提高沟通技巧,提高团队协作效率。
  4. 时间管理:通过合理的时间管理方法,提高工作效率。

研发效能的提升需要团队和个人共同努力,团队和个人都需要不断学习和提高,才能实现最优的

(P.S.:这里最后三个字就是「最优的」,真的不是小编漏了 0.0)

LigaAI 说两句:别看 ChatGPT 洋洋洒洒地输出了几百字,看似结构清晰、论点充足,但仔细一看问题就出现了:

  1. 内容局限性。 ChatGPT 根据预先给定的主题范围(敏捷开发、冲突指导、技术成长、研发团队管理、项目管理)提供的回答,有些刻板和单薄。
  2. 内容质量低 小编愿称第二段内容为「废话文学天花板」,车轱辘话连轴转,看似有条有理,但有实践意义的指南却一点没提。
  3. 完整性不足。 尚未触发字数限制的情况下,ChatGPT 不止一次「卡壳下线」,最终只好以不完整的内容匆匆结尾。

第二部分:什么是「正确的事」?

Q3:管理学常说,要先做正确的事,再正确地做事。对研发团队而言,「做正确的事」和「正确地做事」分别指什么?

ChatGPT: 「做正确的事」是指团队的研发活动要专注于最关键的任务,致力于最有价值、最有影响力和最相关的项目,而这些项目总是与组织的目标和优先事项保持一致。

「正确地做事」指的是有效且高效地执行工作,包括正确地使用工具和技术、遵循敏捷开发流程和原则、建立良好的沟通机制和团队合作环境、不断提高个人和团队的技能水平等。

追问:再展开说说吧。

ChatGPT: 好的。进一步阐述「做正确的事」:

  • 确定优先级并向客户交付价值:了解客户的需求和痛点,并利用有效信息确定团队工作的优先次序;灵活响应变化的客户需求和反馈,并根据需要不断调整优先排序。
  • 与组织目标和优先事项保持一致:团队的工作应与组织的总体目标和优先事项保持一致。这有助于确保团队在正确的方向上集中发力,能更好地促成组织成功。
  • 定期评估和调整:团队应定期评估工作的优先事项并根据利益相关者的反馈、市场动态和业务要求,调整方法。这有助于确保团队始终致力于最有价值的、有影响的和相关的项目。

进一步阐述「正确地做事」:

  • 有效且高效地工作:使用最佳实践和经过验证的方法,交付高质量的结果,其中包含对持续改进、协作和透明度的关注,以及使用数据和指标推动决策并衡量进展。
  • 采用敏捷思维和实践:敏捷方法旨在支持团队以迭代和增量的方式为客户交付价值,并响应变化。采用敏捷思维和实践可以让团队更加灵活和反应迅速。
  • 衡量和分析绩效:定期衡量绩效水平并分析其结果,确定待改进空间并持续改进。这有助于确保团队始终以最有效和高效的方式工作,并交付满足客户需求的高质量结果。

LigaAI 说两句:用中文描述这个问题时,ChatGPT 再一次出现了内容中断的情况,于是我们尝试用英文提问,这才顺利得到上面的结果。

段落内容的灵活性和质量依旧有很大的优化空间,但令人惊喜的是,在缺乏清晰的追问描述的情况下,ChatGPT 也能很好地理解上下文,并给出高度相关的回答。

Q4:是否存在可靠的数据指标,可以判断团队是否在做「正确的事」?

ChatGPT: 有几个指标可以用来判断研发团队是否在做「正确的事」:

  • 客户反馈:包括调查、用户测试和来自客户的其他形式的直接反馈。
  • 业务指标:收入、线索拉新和留存以及市场份额等关键业务指标,可以提供团队价值交付的高级图景。
  • 功能活跃度:衡量用户对新功能的采用和接纳程度,了解团队解决问题和交付价值的能力。
  • 产品使用情况:分析产品使用模式和用户行为,确定优化空间和价值领域机会。
  • 上线周期:衡量团队交付新功能的速度,反映团队的效率和效力。
  • 开发成本:衡量开发和交付新功能的成本,用于评估团队的效率和效力。

这些是几个用于判断研发团队的价值提供的数据指标,而具体指标的选择将取决于企业和产品的独特需求和目标。

LigaAI 说两句:在最初设想中,ChatGPT 应该从技术管理者或者 C-Level 的视角,考虑企业经营等更多维度的内容。但是,最后的效果好像不是这样 TAT

同时还出现了一个新的问题:ChatGPT 似乎在信息处理上不太严谨。 描述的后置语中重复程度最高的两个词分别是「交付价值」和「效率和效力」,而「效率和效力」却不是「做正确的事」的考虑内容。

P.S.:为了更好地阅读体验,后续内容均对 ChatGPT 的回答进行适当删减。

Q5:技术管理者如何保证敏捷团队始终在做「正确的事」?

ChatGPT: 作为技术管理者,你可以采取几个步骤来确保敏捷团队始终在「做正确的事」:

  • 清楚地定义产品愿景和目标:让团队了解他们正在努力构建的目标和原因。
  • 制定有效的敏捷流程:可以让团队的任务分配和执行更加有序。
  • 培养协作和沟通的文化:确保团队对产品愿景和目标理解一致,并能为客户提供最大价值。
  • 授权团队自己做决定:赋予开发团队梳理产品待办列表和确定优先顺序的自主权。
  • 定期审查和维护待办列表:待办需求应与产品愿景和目标保持一致。
  • 定期衡量和跟踪关键指标:使用客户反馈、业务指标和产品使用情况等关键指标,衡量团队交付的价值。

LigaAI 说两句:ChatGPT 对 6 个步骤的先后次序处理超出我们的预期。它并不是简单地检索、整理和组织信息,甚至于小编好像真的能感受到 AI 的「思考」过程 °o°

第三部分:效能的文化建设

Q6:问一个「组织文化建设」相关的问题:高效能的研发团队的组织文化是什么样的?

ChatGPT: 高效能的研发团队,其组织文化具备几个关键表征:

  • 清晰的沟通和协作
  • 持续改进
  • 目标清晰统一
  • 成员自主
  • 信任和透明度
  • 以客户为中心

总之,高效能的研发组织文化创造了一个积极、高效的工作环境,支持创新并推动成果。

LigaAI 说两句:在设计问题时,我们特意加入了具体的相关前置语,明确接下来的问题将围绕「组织文化建设」展开,引导 ChatGPT 给出更符合期待、更切题的回答。

Q7:开发、测试、产品经理和外部伙伴之间总是不可避免地存在误解和理解偏差。不同角色之间的清晰沟通和高效协作,应该如何实现?

ChatGPT: 可以通过以下几种方法实现清晰的沟通和高效的协作:

  • 建立有效的沟通渠道和协议:通过每日站会、回顾会和清晰的文档,同步项目更新、进度和潜在障碍。
  • 优化流程和程序:消除协作和沟通的混乱情况,确保每个人都按照相同的标准工作。
  • 明确角色和职责:明确定义每个成员的角色和职责,避免重叠和混淆,有助于消除误解。
  • 培养信任和透明的文化:通过定期分享和公开讨论,鼓励团队公开讨论想法、挑战和机遇。
  • 实施敏捷方法:Scrum 或看板等敏捷方法可以提供结构化的项目管理方法,促进团队更紧密高效地协作。
  • 组建跨职能团队:跨职能团队可以确保每个人都了解项目大局并可以有效协作。
  • 强调持续学习:鼓励成员不断学习新技能和新技术,在硬实力上减少误解并促进协作。
  • 采用协作工具:选择合适的项目管理、远程办公和研发协作等软件,帮助团队更有效地沟通和协作。

LigaAI 说两句:这是一个实操性很强的具体场景问题,而 ChatGPT 的表现也很值得探讨。

对沟通渠道、信息透明、敏捷开发和工具应用等主题,AI 能够根据丰富的示例和文章整理出可操作建议;而流程优化、团队建设、持续学习等高度依赖个人实践经验和总结的话题,ChatGPT 的回答则不免空泛。


此次对话期间,LigaAI 不止一次地感叹 GPT-3.5 模型惊人的语言能力。相比初代 GPT-3,现在的 ChatGPT 语言流畅通顺、结构框架清晰,虽然「卡壳掉线」的情况偶有发生,但是在语言建模、指令微调和思维链等方面的表现已足以称得上真正的人工智能」

当然,ChatGPT 也存在一些局限:内容准确性难以保证、质量不稳定、空泛建议多而实操性不高、不够灵活等等。输出的内容质量和篇幅长度不成比例时,会让人有种「嘴碎又倔强」的感觉。

此外,在与 ChatGPT 不断周旋的过程中,LigaAI 发现想要发挥 ChatGPT 最大的能力,让 AI 言之有物,「有效提问」非常重要。使用清晰、具体且聚焦的提示词(Prompt)规束 AI 生成的范围和内容,不断修改和优化提示词,逐步获得更好的输出结果;这也是一个不断学习和调优的过程。

让我们回到文章开头的两个问题

👉 对于企业和研发团队而言,ChatGPT 究竟是威胁还是助力?

👉 同 ChatGPT 一般的 AI 能力将多大程度地帮助组织提升工作效率?

强大如 ChatGPT 的 AI 能力体现在可以快速地在巨量的语料库中,搜集、梳理并总结生成流通度最高的内容范式,为知识工作者提供成熟的、可借鉴的框架与知识,极大程度地提高信息粗炼的效率,进一步成为生产力提效工具。

而那些切实为(研发)组织和企业创造价值的,是对信息的判断和取舍、对知识体系的构想和搭建、对实现目标的判断和决策,而这些正是(当前的)ChatGPT 无法规避的缺陷。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

所以,ChatGPT 火了,有谁的「饭碗」要保不住了吗?

不会的。以 ChatGPT 为首的通用人工智能应用,是个人和企业的生产力加速器,是能让我们牢牢抓紧饭碗的强力胶。

它们可以将我们从耗时费力的「粗采型任务」中解放出来,帮我们完成简单又繁琐的数据收集和预处理工作,让我们有更多时间去梳理逻辑、构想创意、分析利弊,更高效地创造价值,实现价值(就像新一代智能研发协作平台 LigaAI 为广大开发者和研发团队带去的价值一样)。

让工作和生活更加便利,释放更多生产力,才是先进技术存在的意义。

了解更多前沿技术、敏捷开发、项目管理、行业动态等消息,欢迎关注 LigaAI@oschina

也欢迎您 LigaAI – 新一代智能研发协作平台,申请体验我们的产品,并与我们展开更多交流 :)

现向全球公开征集“全球开源技术峰会”议题。

议题征集范围及时长

  • eBPF:45 min(演讲 40 分钟,5 分钟互动)

  • 前端新趋势:45 min

  • Rust:45 min

  • 基础设施与软件架构:45 min

  • 数据与数据库技术:45 min

  • DevOps 前线:45 min

  • 聚焦开源安全:25 min(演讲 20 分钟,5 分钟互动)

  • Web3 宇宙世界:25 min

  • AI is Everywhere:25 min

  • Cloud Native Summit:25 min

  • OSPOCon:25 min

  • Linux 基金会开源教育及人才培养峰会:25 min

议题征集要求

演讲内容切忌空洞无物;同时本次会议聚焦开源相关内容,请勿单纯聊与开源完全无关的内容。分享议题聚焦开源,视不同类型论坛方向,可以讲开源的技术、开源的运营与治理、开源的发展趋势、开源技术的实践、开源的商业化相关等。

技术类型议题需满足以下几点要求:

  • 开源相关,围绕开源进行的主题内容(必须)

  • 技术相关,围绕技术原理,实现逻辑进行的主题内容(必须)

  • 我们希望有更多实践内容,而不是单纯盯着开源项目与技术本身。建议可以从实际的应用场景入手,分享通过开源项目与相关技术去解决问题的实践,包括系统架构演进、难点、解决问题的思路等等

议题征集时间

征集截止时间为 2023 年 3 月 10 日。

议题征集反馈

征集结束后,评审团会统一审核议题。若议题通过,将有工作人员主动联系。

议题征集方式

议题投递网址:https://gotc2023.oschina.net

全球开源技术峰会(Global Open-source Technology Conference),简称 GOTC,是由上海浦东软件园、Linux 基金会亚太区、开放原子开源基金会、开源中国(OSCHINA)联合发起的,面向全球开发者的一场盛大开源技术盛宴。GOTC 2023 将于上海举办,为期 2 天,以行业展览、主题发言、特别论坛、分论坛的形式展现,与会者将一起探讨宇宙、3D 与游戏、eBPF、Web3.0、区块链等热门技术主题,以及开源社区、开源商业化、开源教育培训、云原生等热门话题,探讨开源未来,助力开源发展。

官网地址:https://gotc2023.oschina.net


2021 年首届 GOTC 圆满举办,获得热烈反响。(首届 GOTC:https://gotc.oschina.net/)

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

 

勾股OA办公系统是一款简单实用的开源的企业办公系统。系统集成了系统设置、人事管理、行政管理、消息管理、企业公告、知识库、审批流程设置、办公审批、日常办公、财务管理、客户管理、合同管理、项目管理、任务管理等功能模块。系统简约,易于功能扩展,方便二次开发,可以用来做日常OA,CRM,ERP,业务管理等系统。

勾股OA4.24.10发布啦,这是2023年春节后开工的一个小版本的更新,该版本主要更新了如下功能:

🔴更新日志:

1、客户状态显示错误bug修正;
2、工作台快捷填写工作汇报按钮,报错问题修正;
3、客户模块新增按照所属员工检索条件;
4、审批模块转正、离职、转岗审批添加时新增员工弹层选择效果;
5、对个各个内容列表页的最小宽度cellMinWidth统一设置处理;
6、去除工作汇页面报多余的标签,工作日历样式微调整;
7、修复任务列表多条件搜索 or、 and联合查询的语法错误;
8、解决消息定时轮询当为空时,不变更消息提示数字;
9、判断是否有消息内容如果没有消息内容不提示;
10、人力资源->人事调动->编辑报错问题修复;
11、新增海军蓝主题,优化左边菜单体验效果:如果菜单太长时,滚动条默认不出现,鼠标接触菜单时才出现;
12、修复优化了已知的其他问题。

内置模块

  • 配置管理:对系统的常规配置信息进行维护,网站配置管理功能统一维护。
  • 用户管理:维护管理系统的用户,常规信息的维护与账号设置。
  • 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
  • 权限角色:角色菜单管理与权限分配、设置角色所拥有的菜单权限。
  • 部门管理:管理系统组织架构,对组织架构进行统一管理维护。
  • 岗位管理:管理用户担任的岗位。
  • 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
  • 基础数据:对系统中常用的较为固定的数据进行统一维护。
  • 消息通知:系统通知私信信息等管理。
  • 企业公告:企业公告信息发布维护。
  • 办公审批:支持人事、财务、行政、业务等多审批流程。
  • 日常办公:日程、计划、周报、日报等信息化办公工具。
  • 财务管理:财务报销、开票、到账,财务数据规范化管理。
  • 客户管理:统一管理客户,沉淀客户资产,避免客户流失。
  • 合同管理:合同维护、审批、执行、变更、关闭全流程管理。
  • 项目管理:项目操作记录全覆盖跟踪,项目进度一目了然,任务分派,工时记录。
  • 知 识 库:公司制度,工作经验、行业知识归类管理。

软件信息

  • 软件名称:勾股 OA
  • 开源地址:https://gitee.com/gouguopen/office
  • 官网网址:https://www.gougucms.com/home/pages/detail/s/gouguoa.html
  • 文档网址:https://blog.gougucms.com/home/book/detail/bid/3.html

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

漏洞描述

Apache NiFi 是一个用于处理和分布数据的开源系统。

由于 Apache NiFi 1.2.0 到 1.19.1 版本中的 ExtractCCDAAttributes 类不限制 XML 外部实体的引用,导致包含 ExtractCCDAAttributes 处理器的配置流容易受到 XML 外部实体攻击。攻击者可传入包含特制的 DTD(具有恶意 XML 外部实体引用)的 XML 文档获取系统中的任意文件。

漏洞名称 Apache NiFi 存在 xml 外部实体引用不当漏洞 漏洞类型 XXE 发现时间 2023-02-10 漏洞影响广度 小 MPS编号 MPS-2023-0543 CVE编号 CVE-2023-22832 CNVD编号 –

影响范围

org.apache.nifi:nifi-nar-bundles@[1.2.0, 1.20.0)

修复方案

升级org.apache.nifi:nifi-nar-bundles到 1.20.0 或更高版本

参考链接

https://www.oscs1024.com/hd/MPS-2023-0543

https://nvd.nist.gov/vuln/detail/CVE-2023-22832

https://nifi.apache.org/security.html#CVE-2023-22832

https://github.com/apache/nifi/pull/6828/commits/68a10536a8efe8acdfe92c9fffde8326e8

免费情报订阅&代码安全检测

OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通过配置飞书、钉钉、企业微信机器人获取一手的情报。

免费代码安全检测工具: https://www.murphysec.com/?src=osc

免费情报订阅: https://www.oscs1024.com/cm/?src=osc

具体订阅方式详见: https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

对科技行业来说,2023 年应该是比较艰难的一年,目前已有多个大型科技公司都宣布了裁员,其中包括微软、亚马逊、Google 和 Facebook 等。

今天微软旗下的 GitHub,以及同一领域的竞争对手 GitLab 也公布了裁员计划,其中 GitHub 将裁员 10%,GitLab 将裁员 7%,两家公司都没有具体说明受影响员工的确切人数(GitHub 独立运营,微软此前宣布裁员 1 万名员工并不影响 GitHub)。

Idea激活2023.1.3(IntelliJ IDEA 2023.1 EAP 3 发布)

不过根据去年 GitLab 的 10-K 报告显示,该公司的员工人数为 1630 人,虽然现在员工数量肯定会有些变化,但这意味着此次裁员将差不多影响到 100+ 员工。GitHub 目前则是拥有约 3000 名员工,此次裁员则是会影响约 300 人。

GitLab 联合创始人兼首席执行官 Sid Sijbrandij 表示:

目前的宏观经济环境很严峻,因此我们的客户仍然在支出,但他们对软件投资采取了更保守的态度,并花更多时间做出购买决定。

我曾希望重新安排我们的支出优先顺序以抵御日益严重的全球经济衰退。不幸的是,我们需要采取进一步措施,并使我们的支出速度与我们对负责任的增长的承诺相匹配。

GitLab 于 2021 年在纳斯达克上市,其股票在近几个月中没有太强的表现。目前他们的市值约为 70 亿美,比其 150 亿美的 IPO 估值和 190 亿美的最高市值相比已大幅下降。

GitHub 的发言人则是表示:

我们宣布了一些困难但必要的决定和预算调整,以保护我们的业务在短期内的健康,并给予我们投资于长期战略的能力。

为了节省开支,GitHub 还公布了一些公司政策的变化,比如将员工笔记本电脑的更新时间从三年改为四年;团队将转为使用 Microsoft Teams 进行视频会议,以节省大量开支;除此之外,GitHub 还将关闭其所有的办公室,一部分原因是租约到期,还有一部分原因是这些办公室利用率低,此后 GitHub 将转向远程优先的办公模式。

GTK 核心开发者近日组织了一场线下会议,讨论了关于当前 GTK4 的重点开发工作,以及 GTK5 的未来开发计划。

GTK (GIMP Toolkit) 是一套跨多种平台的图形工具包,最初为 GIMP 而写,GIMP 是指 GNU 图像处理程序 (GNU Image Manipulation Program),GIMP 拥有几乎所有图象处理所需的功能,号称 Linux 下的 Photoshop。GTK 后来发展成为 Linux 下开发图形界面应用的主流开发工具。

对于 GTK4,他们讨论的内容包括:

  • 改进图标处理和图标主题规范 (GtkIconTheme)
  • Idea激活2023.1.3

  • 尝试使用比 C 更具表现力的不同语言和更强大的编译器来替换开发较小的组件。这里除了技术方面的考量外,还有Idea激活2023.1.3一个原因是使用不同语言编写新代码可能会带来新的贡献者
  • 改进输入处理
  • 改机平台库

除了 GTK4,核心开发者们还讨论了关于下一个主要版本 GTK5 的开发计划,,以便开始促进 API 中断和删除不推荐使用的代码。

由于 GTK 4.12 计划的颜色管理工作,目前的共识似乎是在 GTK 4.12 发布后开启新分支 GTK 4.90——作为 GTK 5 开发工作的启动。 计划是今年年底初步发布,也就是 GTK 4.0 发布后大约 3 年。过去曾讨论过每两年发布一次主要的 GTK 版本,但这并没有完全实现。去年还谈到可能放弃对 GTK5 的 X11 支持,使其仅支持 Wayland。我们不妨看看这个最终的 GTK5 版本最终会实现哪些变化。

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/122864.html

(0)
上一篇 2024年 7月 24日
下一篇 2024年 7月 24日

相关推荐

关注微信