写点什么

使用 Fluent Bit 实现集中式容器日志记录

  • 2019-09-24
  • 本文字数:16197 字

    阅读完需:约 53 分钟

使用 Fluent Bit 实现集中式容器日志记录

AWS 专为构建师打造。构建师一直致力于寻找优化方法,而应用程序日志记录也是如此。并非所有日志都同等重要。一些日志需要实时分析,而一些日志只需长期存储,以便在需要时进行分析。因此,能够轻松地将日志路由到 AWS 及其合作伙伴提供的各种存储和分析工具非常重要。


正因如此,我们支持在 Fluent Bit 的帮助下创建简单的扩展点,以便将日志从容器化应用程序流式传输到 AWS 和合作伙伴解决方案,从而保留日志并进行分析。新推出的 AWS Fluent Bit 插件以容器映像的形式提供,利用该插件,您可以将日志路由到 Amazon CloudWatch Amazon Kinesis Data Firehose 目标位置(其中包括 Amazon S3、Amazon Elasticsearch ServiceAmazon Redshift)。在本博文中,我们将展示如何在 Amazon ECS 和 EKS 集群上实际运用 Fluent Bit 插件。如果您不熟悉工具,可能还要查看有关 Fluentd 和 Kinesis Firehose 基础知识的教程,并了解 AWS 容器路线图中的相关问题,尤其是 #10#66

日志路由简介

从概念上讲,容器化设置(如 Amazon ECS 或 EKS)中的日志路由如下图所示:



在上图左侧,描述了日志源(从底部开始):


  1. 主机和控制层面级别由 EC2 实例组成,用于托管容器。您可以直接(或不直接)访问这些实例。例如,对于在 Fargate 上运行的容器,您将不会在 EC2 控制台中看到实例。在此级别,您还将获得 AWS 管理的 EKS 控制层面中的日志。

  2. 容器运行时级别通常包括 Docker 引擎生成的日志,例如 ECS 中的代理日志。这些日志通常对具有基础设施管理角色的人员最有用,但也可以帮助开发人员排查问题。

  3. 应用程序级别用于运行用户代码。此级别会生成与特定应用程序有关的日志,例如有关您自己应用程序中的操作结果的日志条目,或现成应用程序组件(如 NGINX)的应用程序日志。


接下来是路由组件:即 Fluent Bit。该组件负责从所有源读取日志,并将日志记录路由到各个目标位置(也称为日志接收器)。此路由组件需要以某种形式运行,例如作为 Kubernetes pod/ECS 任务中的伴生服务,或者作为主机级守护程序集。


下游日志接收器将日志用于不同的目的并供不同的受众使用。其中包括大量使用案例,从日志分析到确保合规性(日志需要在指定的保留期内存储),当人类用户需要收到事件通知时发出提醒;控制面板日志提供(实时)图表集合,帮助人类用户快速了解系统的整体状态。


了解这些基础知识后,下面我们看一个具体的使用案例:使用 Fluent Bit 实现多集群应用程序的集中式日志记录。Amazon ECS Fluent Bit 守护程序服务 GitHub 存储库中提供了所有容器定义和配置。

集中式日志记录的实际应用:多集群日志分析

为了展示 Fluent Bit 在实际中的应用,我们将跨 Amazon ECS 和 Amazon EKS 集群执行多集群日志分析,并将 Fluent Bit 部署和配置为守护程序集。运行在每个集群中的 NGINX 应用程序生成的应用程序级日志由 Fluent Bit 捕获,并通过 Amazon Kinesis Data Firehose 流式传输到 Amazon S3,然后我们可以在这里使用 Amazon Athena 进行查询:


Amazon ECS 设置

在 EC2 集群上使用以下用户数据(在我们的示例中,在名为 enable-fluent-log-driver.sh 的文件中)创建 ECS,以便在 ECS 代理中启用 Fluentd 日志驱动程序:


#!/bin/bashecho "ECS_AVAILABLE_LOGGING_DRIVERS=[\"awslogs\",\"fluentd\"]" >> /etc/ecs/ecs.config
复制代码


注意:此步骤假设您已安装 ECS CLI


例如,我们在 EC2 集群上创建以下 ECS:


$ ecs-cli up \          --size 2 \          --instance-type t2.medium \          --extra-user-data enable-fluent-log-driver.sh \          --keypair fluent-bit-demo-key \          --capability-iam \          --cluster-config fluent-bit-demo
复制代码


接下来,我们需要构建一个包含 Fluent Bit 配置的容器映像。为此,我们将创建一个包含以下内容的 Dockerfile


FROM amazon/aws-for-fluent-bit:1.2.0ADD fluent-bit.conf /fluent-bit/etc/ADD parsers.conf /fluent-bit/etc/
复制代码


注意:此次未遵循良好的安全实践,没有定义 USER,而是让其以 root 身份运行。这是有意而为,因为 Fluent Bit 当前需要以 root 身份运行。


上述 Dockerfile 又依赖两个配置文件:第一个是 fluent-bit.conf


[SERVICE]    Parsers_File parsers.conf
[INPUT] Name forward unix_path /var/run/fluent.sock
[FILTER] Name parser Match ** Parser nginx Key_Name log
[OUTPUT] Name firehose Match ** delivery_stream my-stream region some-region
复制代码


其次是 parsers.conf,用于解析 NGINX 日志:


[PARSER]    Name   nginx    Format regex    Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")? \"-\"$ Time_Key time Time_Format %d/%b/%Y:%H:%M:%S %z
复制代码


现在,我们将构建自定义容器映像,并将其推送到一个名为 fluent-bit-demo 的 ECR 存储库:


# build the custom image$ docker build --tag fluent-bit-demo:0.1 .# push to Amazon ECR:$ ecs-cli push fluent-bit-demo:0.1
复制代码


访问 ECR 控制台,确认映像构建和推送是否成功;您应会看到与下面类似的内容:



现在,我们可以使用上述容器映像启动包含守护程序计划策略的 ECS 服务,以将自定义配置的 Fluent Bit 部署到集群中:


$ aws cloudformation deploy \      --template-file ecs-fluent-bit-daemonset.yml \      --stack-name ecs-fluent-bit-daemon-service \      --parameter-overrides \      EnvironmentName=fluentbit-daemon-service \      DockerImage=XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/fluent-bit-demo:0.1 \      Cluster=fluent-bit-demo \      --region $(aws configure get region) \      --capabilities CAPABILITY_NAMED_IAM
复制代码


在 ECS 控制台中,您现在应会看到与下面类似的内容:



现在,我们可以基于以下任务定义,启动 ECS 服务,即运行 NGINX:


{    "taskDefinition": {        "taskDefinitionArn": "arn:aws:ecs:us-west-2:XXXXXXXXXXXX:task-definition/nginx:1",        "containerDefinitions": [            {                "name": "nginx",                "image": "nginx:1.17",                "memory": 100,                "essential": true,                "portMappings": [                    {                        "hostPort": 80,                        "protocol": "tcp",                        "containerPort": 80                    }                ],                "logConfiguration": {                    "logDriver": "fluentd",                    "options": {                        "fluentd-address": "unix:///var/run/fluent.sock",                        "tag": "logs-from-nginx"                    }                }            }        ],        "family": "nginx"    }}
复制代码


创建上述任务定义之后,现在应该会在 ECS 控制台中看到以下内容:



现在,我们可以基于上述任务定义启动 ECS 服务:


$ aws ecs create-service \      --cluster fluent-bit-demo \      --service-name nginx-svc \      --task-definition nginx:1 \      --desired-count 1
复制代码


如果一切顺利,您应该会在 ECS 控制台中看到与下面类似的内容:



至此,我们已设置好 ECS 部分。现在,我们在 Amazon EKS 上运行的 Kubernetes 集群中配置相同的设置。

Amazon EKS 设置

使用 eksctl 创建一个名为 fluent-bit-demo的 Amazon EKS 集群,如 EKS 文档中所示,然后创建一个名为 eks-fluent-bit-daemonset-policy.json 的策略文件(来源),其中包含以下内容:


{    "Version": "2012-10-17",    "Statement": [        {            "Effect": "Allow",            "Action": [                "firehose:PutRecordBatch"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": "logs:PutLogEvents",            "Resource": "arn:aws:logs:*:*:log-group:*:*:*"        },        {            "Effect": "Allow",            "Action": [                "logs:CreateLogStream",                "logs:DescribeLogStreams",                "logs:PutLogEvents"            ],            "Resource": "arn:aws:logs:*:*:log-group:*"        },        {            "Effect": "Allow",            "Action": "logs:CreateLogGroup",            "Resource": "*"        }    ]}
复制代码


要将此策略文件附加到 EC2 工作线程节点上的 EKS,请按以下顺序执行操作:


$ STACK_NAME=$(eksctl get nodegroup --cluster fluent-bit-demo -o json | jq -r '.[].StackName')
$ INSTANCE_PROFILE_ARN=$(aws cloudformation describe-stacks --stack-name $STACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="InstanceProfileARN") | .OutputValue')
$ ROLE_NAME=$(aws cloudformation describe-stacks --stack-name $STACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="InstanceRoleARN") | .OutputValue' | cut -f2 -d/)
$ aws iam put-role-policy \ --role-name $ROLE_NAME \ --policy-name FluentBit-DS \ --policy-document file://eks-fluent-bit-ds-policy.json
复制代码


现在我们继续定义 Kubernetes RBAC 设置,即 Fluent Bit pod 将使用的服务账户以及角色和角色绑定。


首先创建服务账户 fluent-bit(稍后我们将在守护程序集中使用):


$ kubectl create sa fluent-bit
复制代码


接下来,在名为 eks-fluent-bit-daemonset-rbac.yaml 的文件(来源)中定义角色和绑定:


apiVersion: rbac.authorization.k8s.io/v1beta1kind: ClusterRolemetadata:  name: pod-log-readerrules:- apiGroups: [""]  resources:  - namespaces  - pods  verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1beta1kind: ClusterRoleBindingmetadata:  name: pod-log-crbroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: pod-log-readersubjects:- kind: ServiceAccount  name: fluent-bit  namespace: default
复制代码


现在,通过执行 kubectl apply -f eks-fluent-bit-ds-rbac.yaml,创建上面定义的角色和角色绑定。


接下来,在名为 eks-fluent-bit-configmap.yaml 的文件(来源)中通过 Kubernetes 配置映射定义 Fluent Bit 配置:


apiVersion: v1kind: ConfigMapmetadata:  name: fluent-bit-config  labels:    app.kubernetes.io/name: fluentbitdata:  fluent-bit.conf: |    [SERVICE]        Parsers_File  parsers.conf    [INPUT]        Name              tail        Tag               kube.*        Path              /var/log/containers/*.log        Parser            docker        DB                /var/log/flb_kube.db        Mem_Buf_Limit     5MB        Skip_Long_Lines   On        Refresh_Interval  10    [FILTER]        Name parser        Match **        Parser nginx        Key_Name log    [OUTPUT]        Name firehose        Match **        delivery_stream eks-stream        region us-west-2   parsers.conf: |    [PARSER]        Name   nginx        Format regex        Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")? \"-\"$ Time_Key time Time_Format %d/%b/%Y:%H:%M:%S %z
复制代码


通过执行 kubectl apply -f eks-fluent-bit-confimap.yaml 应用此配置映射,然后在名为 eks-fluent-bit-daemonset.yaml 的文件(来源)中定义 Kubernetes 守护程序集(使用提到的配置映射):


apiVersion: apps/v1kind: DaemonSetmetadata:  name: fluentbit  labels:    app.kubernetes.io/name: fluentbitspec:  selector:    matchLabels:      name: fluentbit  template:    metadata:      labels:        name: fluentbit    spec:      serviceAccountName: fluent-bit      containers:      - name: aws-for-fluent-bit        image: amazon/aws-for-fluent-bit:1.2.0        volumeMounts:        - name: varlog          mountPath: /var/log        - name: varlibdockercontainers          mountPath: /var/lib/docker/containers          readOnly: true        - name: fluent-bit-config          mountPath: /fluent-bit/etc/        - name: mnt          mountPath: /mnt          readOnly: true        resources:          limits:            memory: 500Mi          requests:            cpu: 500m            memory: 100Mi      volumes:      - name: varlog        hostPath:          path: /var/log      - name: varlibdockercontainers        hostPath:          path: /var/lib/docker/containers      - name: fluent-bit-config        configMap:          name: fluent-bit-config      - name: mnt        hostPath:          path: /mnt
复制代码


最后,通过执行以下命令启动 Fluent Bit 守护程序集:


$ kubectl apply -f eks-fluent-bit-daemonset.yaml
复制代码


通过查看日志,验证 Fluent Bit 守护程序集:


$ kubectl logs ds/fluentbitFound 3 pods, using pod/fluentbit-9zszmFluent Bit v1.1.3Copyright (C) Treasure Data
[2019/07/08 13:44:54] [ info] [storage] initializing...[2019/07/08 13:44:54] [ info] [storage] in-memory[2019/07/08 13:44:54] [ info] [storage] normal synchronization mode, checksum disabled[2019/07/08 13:44:54] [ info] [engine] started (pid=1)[2019/07/08 13:44:54] [ info] [in_fw] listening on unix:///var/run/fluent.sock...[2019/07/08 13:44:55] [ info] [sp] stream processor started
复制代码


接下来,通过 kubectl apply -f eks-nginx-app.yaml 部署以下 NGINX 应用程序


apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx  labels:    app.kubernetes.io/name: nginxspec:  replicas: 4   selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.17        ports:        - containerPort: 80---apiVersion: v1kind: Servicemetadata:  name: nginx  labels:    app: nginxspec:  ports:  - port: 80    targetPort: 80  selector:    app: nginx
复制代码


至此,我们已完成日志源和路由设置。现在,我们将使用从在 ECS 和 EKS 中运行的 NGINX 容器收集的所有日志数据执行实际任务:我们将对日志进行集中分析。

跨集群执行日志分析

目标是对在 ECS 和 EKS 集群中运行的 NGINX 容器进行日志分析。为此,我们使用 Amazon Athena,这样可以使用 SQL 以交互方式从 Amazon S3 查询服务日志数据。但是,在查询 S3 中的数据之前,我们需要从中获得日志数据。


请注意,在上述 ECS 和 EKS 的 Fluent Bit 配置中,我们将输出设置为 delivery_stream xxx-stream。 这是 Amazon Kinesis Firehose 传输流,我们需要先为 ECS 和 EKS 创建传输流。


首先,通过定义允许 Firehose 写入 S3 的有效策略来设置访问控制部分。为此,我们需要使用两个策略文件创建一个新的 IAM 角色。第一个是 firehose-policy.json来源):


{  "Version": "2012-10-17",  "Statement": {      "Effect": "Allow",      "Principal": {        "Service": "firehose.amazonaws.com"      },      "Action": "sts:AssumeRole"  }}
复制代码


第二个是 firehose-delivery-policy.json 策略文件(来源),在该文件中,将 XXXXXXXXXXXX 替换为您自己的账户 ID(如果您不确定 ID 是什么,可以通过执行 aws sts get-caller-identity --output text --query 'Account' 获取)。同样,在 S3 部分,将 mh9-firelens-demo 替换为您自己的存储桶名称。


现在,我们可以创建 firehose_delivery_role,以用于 ECS 和 EKS 传输流:


$ aws iam create-role \        --role-name firehose_delivery_role \        --assume-role-policy-document file://firehose-policy.json
复制代码


记下上述命令 JSON 输出结果中的角色 ARN,其格式为 arn:aws:iam::XXXXXXXXXXXXX:role/firehose_delivery_role。我们稍后在创建传输流时会用到,但在创建传输流之前,我们必须实施在 firehos- delivery-policy.json 中定义的策略:


$ aws iam put-role-policy \        --role-name firehose_delivery_role \        --policy-name firehose-fluentbit-s3-streaming \        --policy-document file://firehose-delivery-policy.json
复制代码


现在,创建 ECS 传输流:


$ aws firehose create-delivery-stream \            --delivery-stream-name ecs-stream \            --delivery-stream-type DirectPut \            --s3-destination-configuration \RoleARN=arn:aws:iam::XXXXXXXXXXXX:role/example_firehose_delivery_role,\BucketARN="arn:aws:s3:::mh9-firelens-demo",\Prefix=ecs
复制代码


注意:以上命令中的空格很重要:RoleARN 等必须位于一行中且不含空格。


现在,我们必须对 EKS 传输流重复以上操作,重用在第一步中创建的角色。(换句话说,您只需重复执行 aws firehose create-delivery-stream 命令,将 ecs-stream 替换为 eks-stream,将 Prefix=ecs 替换为 Prefix=eks 即可。)


创建并激活传输流需要几分钟时间。当您看到与下面类似的内容时,表示您可以进行下一步:



现在,我们需要为在 ECS 和 EKS 中运行的 NGINX 容器生成一些负载。您可以获取 ECSEKS 的负载生成器文件并执行以下命令;这将每两秒对相应的 NGINX 服务执行一次 curl 操作(在后台执行),直到您终止脚本。


$ ./load-gen-ecs.sh &$ ./load-gen-eks.sh &
复制代码


现在我们有了来自 NGINX Web 服务器的一些日志数据,便可以通过 Athena 查询 S3 中的日志条目。为此,我们必须首先为 ECS 和 EKS 创建表,告知 Athena 我们正在使用的架构(下面显示了 ECS 日志数据的架构,对于 EKS,也是如此):


CREATE EXTERNAL TABLE fluentbit_ecs (    agent string,    code string,    host string,    method string,    path string,    referer string,    remote string,    size string,    user string)ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'LOCATION 's3://mh9-firelens-demo/ecs2019/'
复制代码


注意:Amazon Athena 不导入或提取数据;它直接在 S3 中查询数据。因此,当日志数据通过 Fluent Bit 和 Firehose 传输流从 NGINX 容器到达 S3 存储桶中时,您可以使用 Athena 进行查询。


接下来,使用以下 SQL 语句,创建 ECS 和 EKS 日志条目的整合视图


CREATE OR REPLACE VIEW "fluentbit_consolidated" ASSELECT * , 'ECS' as sourceFROM fluentbit_ecsUNIONSELECT * , 'EKS' as sourceFROM fluentbit_eks
复制代码


这样,我们可以合并这两个表(使用相同的架构),再添加一个源以标记源 ECS 或 EKS。现在,我们可以执行 SQL 查询,找出两个集群中使用 NGINX 服务的前 10 位用户


SELECT source,         remote AS IP,         count(remote) AS num_requestsFROM fluentbit_consolidatedGROUP BY  remote, sourceORDER BY  num_requests DESC LIMIT 10
复制代码


这将生成与下面类似的结果:



就这么简单! 您已经成功设置了 Fluent Bit 插件,并在两个不同的托管 AWS 容器环境(ECS 和 EKS)中使用它来执行日志分析。


完成之后,不要忘记删除相应的工作负载,包括 Kubernetes NGINX 服务(它进而会删除负载均衡器),并销毁 EKS 和 ECS 集群(这会销毁其中的容器)。最后但同样重要的一点是,清理包含日志数据的 Kinesis 传输流和 S3 存储桶。


为了未来使用更加便利,我们还在开发一项进一步简化在 AWS Fargate、Amazon ECS 和 Amazon EKS 上安装和配置 Fluent Bit 插件的功能。您可以通过 AWS 容器路线图的问题 10 关注该功能。

性能和后续步骤说明

为了更好地了解性能,我们执行了基准测试,将上面的 Fluent Bit 插件与 Fluentd CloudWatchKinesis Firehose 插件进行了比较。我们所有的测试都是在 c5.9xlarge EC2 实例上执行的。 结果如下:


CloudWatch 插件:Fluentd 与 Fluent Bit


每秒日志行数数据输出Fluentd CPUFluent Bit CPUFluentd 内存Fluent Bit 内存
10025KB/秒0.013 vCPU0.003 vCPU146MB27MB
1000250KB/秒0.103 vCPU0.03 vCPU303MB44MB
100002.5MB/秒1.03 vCPU0.19 vCPU376MB65MB


测试表明,Fluent Bit 插件比 Fluentd 更节省资源。平均而言,Fluentd 使用的 CPU 是 Fluent Bit 插件的 4 倍以上,所用内存是 Fluent Bit 插件的 6 倍以上。


Kinesis Firehose 插件:Fluentd 与 Fluent Bit


每秒日志行数数据输出Fluentd CPUFluent Bit CPUFluentd 内存Fluent Bit 内存
10025KB/秒0.006 vCPU0.003 vCPU84MB27MB
1000250KB/秒0.073 vCPU0.033 vCPU102MB37MB
100002.5MB/秒0.86 vCPU0.13 vCPU438MB55MB


在此基准测试中,平均而言,Fluentd 使用的 CPU 和内存分别是 Fluent Bit 插件的 3 倍和 4 倍以上。请注意,这些数据并未提供任何保证;您占用的资源可能有所不同。不过,上述数据点表明 Fluent Bit 插件的效率显著高于 Fluentd。

后续步骤

我们很高兴您能够在自己的集群上尝试此插件。如果某些操作未按预期运行,请告知我们,并且请分享您对性能/资源占用以及使用案例的见解。请就 GitHub 中的问题留言,或者在 GitHub 上提出有关 AWS 容器路线图的问题。

作者简介

Wesley Pettit,AWS 容器服务团队的软件开发人员。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/centralized-container-logging-fluent-bit/


2019-09-24 16:083184
用户头像

发布了 1908 篇内容, 共 147.2 次阅读, 收获喜欢 81 次。

关注

评论

发布
暂无评论
发现更多内容

【深入浅出Spring原理及实战】「开发实战系列」重新回顾一下异常重试框架Spring Retry的功能指南和实战

码界西柚

spring Spring retry 重试机制 spring-retry

【深入浅出Spring原理及实战】「开发实战系列」Spring-Cache扩展自定义(注解失效时间+主动刷新缓存)

码界西柚

spring Spring Cache 缓存控制 缓存能力

《自动机理论、语言和计算导论》阅读笔记:p428-p525

codists

编译原理

CCE云原生混部场景下的测试案例

华为云开发者联盟

云原生 华为云 华为云开发者联盟 华为云CCE

基于国产 Web 组态软件 TopStack 搭建隧道照明控制系统

图扑物联

物联网 组态软件 web组态 智慧隧道

大数据基础工程技术团队4篇论文入选ICLR,ICDE,WWW

阿里云大数据AI技术

大数据 阿里云

Partisia Blockchain 生态zk跨链DEX上线,加密资产将无缝转移

BlockChain先知

DcmMWL-SDK

birdbro

andiod Java' DICOM

聚道云助力航空巨头,管理与信息化效率飙升!

聚道云软件连接器

案例分享

深度探究:职业发展必备——能力模型解析

测试人

软件测试

【深入浅出Spring原理及实战】「工作实战专题」叫你如何使用另类操作去实现Spring容器注入Bean对象 (1)

码界西柚

Java spring 框架 Bean处理

Partisia Blockchain 生态首个zk跨链DEX现已上线

石头财经

Xilinx ZYNQ的应用开发介绍

芯动大师

开发板 驱动 ZYNQ

Partisia Blockchain 生态zk跨链DEX上线,加密资产将无缝转移

股市老人

GreptimeDB 助力国家电网数字换流站打造稳定高效的时序数据底座

Greptime 格睿科技

时序数据库 国产化 智慧电网 国家电网

营销H5测试综述

京东零售技术

测试 企业号 5 月 PK 榜

国内小白用什么方法充值使用ChatGPT4.0?

蓉蓉

openai GPT-4 ChatGPT4

Go-Zero技能提升:深度探究goctl的妙用,轻松应对微服务开发挑战!(三)

王中阳Go

Go golang 微服务 Go进阶 gozero

豆瓣8.7分,30000人都在阅读的量化用户体验实操书全面更新!

博文视点Broadview

使用 Fluent Bit 实现集中式容器日志记录_容器_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章