解决方案:56 条评论 “搜索引擎优化步骤”

优采云 发布时间: 2022-11-20 08:25

  解决方案:56 条评论 “搜索引擎优化步骤”

  写了半年的帖子,很多读者反映有点锤子和棍子的感觉,没有办法掌握搜索引擎优化的全过程。一些读者还建议写一本 SEO 教程之类的书。我暂时没有时间和精力写这样一本书,以后再说吧。

  搜索引擎优化过程中的大部分内容,在之前的帖子中都有涉及到,所以今天我将对之前的帖子做一个总结和链接,方便还没有掌握搜索引擎优化的读者系统地阅读。

  首先,如果是新站,先做市场调查,搞清楚自己应该卖什么。找到用户需要什么,或者需要解决的问题,然后在此基础上开发产品或者寻找产品来源。

  然后注册一个合适的域名。

  在开始建站之前,首先要对行业和竞争对手有一个大概的了解,这样才能清楚自己需要做多少工作。如果您向其他人提供 SEO 服务,则必须教育您的客户并确定您自己的价格结构。了解客户网站盈利模式,对客户现有网站进行健康诊断。

  下一步是进行关键词研究,找到那些搜索量大、竞争少的关键词,做好主关键词和长尾关键词的配置。

  在开始设计网站之前,首先要想好网站应该有哪些内容。具体的栏目要提前规划好,网页的内容也要提前规划好。

  

" />

  设计网站时,要保证网站结构合理,URL静态化,是二级域名还是目录都要事先考虑好。

  网站设计也应该有一定的可扩展性。

  在设计每个具体的网页时,注意把关键词放在自然该放的地方。

  网站内容在编写时也考虑到了词干提取技术和语义分析。

  网站流量统计也是必要的。

  找一个稳定的托管服务商,开一个网站。网站打开时最好有一定的规模。

  网站上线后,就要开始外链建设了。链接不仅需要数量,还需要质量。链接文本也会更改。应控制链路增加速度。

  

" />

  不要作弊。

  优化的一般原则是自然和平衡。

  一般来说,新域名会在谷歌沙盒中停留数月,甚至长达一年。在此期间,我们应该仔细观察网站的流量统计。一方面要看百度和雅虎的收录和排名,另一方面要从流量统计中找出更多关键词的扩展内容。

  同时,在网站处于沙盒期间,可以不断增加网站的内容,网站的扩张速度不宜过快。

  网站在各个搜索引擎中有了一定的排名后,就要观察它与排名靠前的网站的区别。

  搜索引擎排名算法在不断变化,因此您需要注意并及时调整您的SEO策略。

  以上只是一个基本的大概流程,还有很多东西是SEO技巧无法体现的。比如用户行为模式、社交搜索等,这些都需要长期的积累和经验。

  解决方案:一文详解K8s环境下Job类日志采集方案

  背景

  K8s丰富的控制器为容器编排提供了极大的便利。针对单任务和定时任务的需求,K8s提供了Job和Cronjob控制器来满足非驻留容器编排的需求。由于这种非常驻特性,任务容器的持续时间可能会很短(比如定时清理数据的任务),甚至有的任务可能因为一启动就运行失败而秒退出,这给Job日志的采集

带来很大困难。挑战。

  本文将探讨基于高性能轻量级可观察采集

器iLogtail的各种作业日志采集

方案,分析这些方案在不同场景下日志采集

所能达到的稳定性保障和方案优化空间。

  作业容器的特点

  为了表述方便,本文将Job控制器控制的所有服务容器统称为Job容器。与其他类型的容器相比,Job容器有以下特点:

  增删频度高:作业容器往往是周期性或按需调度,执行完立即结束,因此增删频度明显高于其他类型的容器。生命周期短:Job容器的期望是执行完任务就退出,不是常驻服务,所以生命周期比较短。有些作业仅用于简单地删除历史数据等,其生命周期仅以秒为单位。

  大爆发并发:作业容器常用于编排批任务或测试场景。此类场景往往会瞬间触发大量Job容器实例的生成,并伴随着大量日志的生成。

  选择作业日志采集

解决方案的主要考虑因素

  因此,以下三个注意事项对于Job日志采集

非常重要。容器发现速度:作业容器的增删频繁。如果容器发现速度太慢,可能还没有发现容器就已经销毁了,更谈不上采集

数据了。延迟开始采集

:Job 容器的生命周期可能很短。当 K8s 中的 Pod 被销毁时,其下的所有容器数据都会被删除。如果不及时开始采集

,则无法锁定文件句柄,无法采集

被删除的文件数据。. 弹性支持:Job容器的突发性高并发特性,非常适合使用弹性资源来节省成本,所以相应地,希望采集方案能够适配支持弹性伸缩。同时,在选择方案时也需要考虑容器日志采集

的一些常见需求。资源开销:较低的资源开销通常意味着较低的成本,同时也降低了日志采集

对业务资源使用的影响。元信息标记:元信息用于标识日志的来源,丰富的元信息有助于日志的查找和使用。侵入性:侵入性决定了采集日志的开发成本。同时,更强的侵入性也会增加日志采集与业务的耦合度,给未来的方案修改和升级带来潜在的成本。较低的资源开销通常意味着较低的成本,同时也降低了日志采集

对业务资源使用的影响。元信息标记:元信息用于标识日志的来源,丰富的元信息有助于日志的查找和使用。侵入性:侵入性决定了采集日志的开发成本。同时,更强的侵入性也会增加日志采集与业务的耦合度,给未来的方案修改和升级带来潜在的成本。较低的资源开销通常意味着较低的成本,同时也降低了日志采集

对业务资源使用的影响。元信息标记:元信息用于标识日志的来源,丰富的元信息有助于日志的查找和使用。侵入性:侵入性决定了采集日志的开发成本。同时,更强的侵入性也会增加日志采集与业务的耦合度,给未来的方案修改和升级带来潜在的成本。侵入性决定了采集日志的开发成本。同时,更强的侵入性也会增加日志采集与业务的耦合度,给未来的方案修改和升级带来潜在的成本。侵入性决定了采集日志的开发成本。同时,更强的侵入性也会增加日志采集与业务的耦合度,给未来的方案修改和升级带来潜在的成本。

  iLogtail容器采集

方案对比

  DaemonS优采云

采集器

方式

  DaemonS 优采云

采集器

方法利用K8s的DaemonSet控制器在每个节点上部署一个iLogtail容器,用于节点上所有容器的日志采集。这种部署方式通过与docker通信来发现节点上的所有容器。数据采集​​。

  这种采集

方式的好处是非常明显的。每个节点只需要部署一个采集容器,无论应用容器有多少,都非常节省资源。可以获得完整的容器元信息,应用程序不知道采集

容器,完全没有入侵。

  另一方面,DaemonSet方法在与Job日志采集

密切相关的三个关键点上表现一般。通过DaemonSet部署iLogtail时,iLogtail发现容器的机制依赖于与docker.sock或containerd.sock通信。Docker有自己的EventListener机制,实时获取容器的创建和销毁事件;containerd 没有,只​​能通过轮询机制了解它。容器的创建和销毁,最新版本的轮询间隔是1秒,所以可以认为iLogtail发现容器的延迟是1秒。从发现容器到开始采集

数据有大约 3-6 秒的延迟。采集

stdout的延迟来自stdout采集

插件内部的轮询间隔,而采集

容器文件的延迟来自docker_file插件的轮询。C++核心部分加载最新容器配置的时间间隔和频率限制。因此,加上一些耗时的处理,预计DaemonSet方法中的容器日志采集

延迟大约为5-8秒。在弹性方面,DaemonSet部署的iLogtail可以支持节点动态扩展,但不能直接支持没有物理节点的容器弹性扩展。再加上一些耗时的处理,预计DaemonSet方法中的容器日志采集

延迟大约为5-8秒。在弹性方面,DaemonSet部署的iLogtail可以支持节点动态扩展,但不能直接支持没有物理节点的容器弹性扩展。再加上一些耗时的处理,预计DaemonSet方法中的容器日志采集

延迟大约为5-8秒。在弹性方面,DaemonSet部署的iLogtail可以支持节点动态扩展,但不能直接支持没有物理节点的容器弹性扩展。

  Sidecar采集

方式

  sidecar采集方式利用K8s同一个Pod中的容器可以共享存储卷的特性,在一个业务Pod中同时部署业务和采集容器,达到业务数据的目的。这种采集方式需要业务容器挂载需要采集的目录共享给采集容器,采集容器采用采集本地文件的方式采集业务容器日志。

  本质上,这种方式与主机采集

没有太大区别,不需要关心容器发现。同时,只要采集

容器不退出,Pod就会处于Running状态,共享存储卷上的文件不会被删除,不用担心因为以下原因造成的数据丢失开始采集

的延迟。由于与业务容器Pod一起部署,Sidecar还可以灵活支持各种弹性伸缩方案,因此在Job容器集合的关键三点表现出色。

  不过与DaemonSet相比,Sidecar并没有那么受欢迎。除了不能直接支持采集

容器的标准输出的功能因素*敏*感*词*。一是资源消耗大。每个Pod都需要一个Sidecar集合容器,其资源开销与业务Pod数量成正比。其次,由于采集原理与宿主机基本相同,因此无法自动采集容器的元信息,需要通过环境变量等方式暴露给采集容器。最后,每个业务Pod都需要为目标数据配置共享存储,还要考虑通知采集

容器退出的机制,有些侵入性。

  ECI弹性容器产品收货方式

  ECI是Elastic Container Instance的缩写(详见阿里云官方介绍)。相当于一个小型虚拟机,用完就销毁,没有物理节点的羁绊。对于突发性高并发场景,它具有成本和弹性优势,这恰好是一些作业容器使用场景的特点。ECI产品采集方式原理与DaemonS优采云

采集器

方式类似,不同的是ECI中的iLogtail容器不受Kube Scheduler控制,而是由ECI控制,对Kube Scheduler不可见用户。iLogtail的容器发现方式不与docker.sock或containerd.sock通信,而是通过静态容器信息发现要采集

的容器。

  ECI产品的采集方式自然为弹性伸缩提供了很好的支持。由于采集原理与DaemonSet类似,ECI采集方式也继承了DaemonS优采云

采集器

的一些特性,比如能够获取完整的元信息,比如容器发现和启动采集的延迟。但是由于ECI产品的采集方式是使用静态文件来发现容器,启动后可以立即找到容器,所以实际延迟要比DaemonSet小很多。

  

" />

  在成本上,虽然每个Pod启动一个ECI,自带一个iLogtail Pod,但是由于弹性容器资源随用随返的特性,对于突发情况,实际成本可能会低于自建节点高并发作业场景。由于ECI只是为需要采集数据的容器创建iLogtail容器,因此需要通过一些手段来确定业务容器的日志采集需求。目前支持 CRD(K8s Operator)或环境变量。CRD方式是目前比较推荐的一种接入方式。不侵入业务容器,支持更丰富的集合配置。如果使用环境变量方式,存在一定的侵入性。

  同容器采集

方法

  同容器采集方式是指将采集流程和业务流程部署在同一个容器中,相当于把容器当成虚拟机的部署方式,所以采集原理和宿主机完全一样。

  这种方式虽然看起来很繁琐,侵入性也很强,但是在老的业务容器化流程中是很常见的。在使用同一个容器部署时,为了保证作业数据不丢失,需要仔细设计容器的退出机制,等待数据采集完成再退出。由于采集进程和业务进程在同一个容器中工作,所以这种采集方式在容器发现和采集启动上没有任何延迟,同时也全面支持各种弹性方案。

  在资源开销上,每个业务容器都会消耗额外的采集过程开销,消耗资源较多。采集

容器的元信息,需要通过环境变量等方式暴露在业务容器中,不能自动标记。

  独立存储采集方式

  独立存储方式是指容器将所有要采集

的数据打印到挂载在共享pv或hostPath上的路径上,采集

容器只需要关心采集

pv或hostPath上数据的采集

方案。一些作业调度程序可以指定每个作业的日志路径,因此日志可以打印在同一个共享卷上。使用shared pv时,所有的数据采集只需要一个采集容器采集即可;使用hostPath时,需要使用DaemonSet来部署采集容器,这样每个节点只有一个采集容器。

  使用独立存储后,数据生命周期与容器生命周期分离,采集容器只需要按照路径采集存储上的数据,不存在发现容器和启动容器的延迟问题采集

。这种采集方式的其他优点还包括采集容器的数量不会随着业务容器的增加而增加,资源占用很低,不会侵入业务容器。

  但是在弹性方面,独立存储采集

方式表现不佳。如果使用PV对应一个采集容器,一个采集容器的吞吐量就会成为采集性能的瓶颈。但是,如果 hostPath 与 DaemonSet 部署一起使用,则无法支持弹性容器。这种获取方式对获取元信息的支持也较差,只能通过在数据存储路径中嵌入元信息来暴露部分元信息。例如,挂载卷时,将 SubPathExpr 设置为 logs/$(POD_NAMESPACE)_$(POD_NAME)_$(POD_IP)_$(NODE_IP)_$(NODE_NAME)。

  概括

  下表总结了上述五种采集方案:

  可以看出,每种方案都各有优缺点,适用于不同的作业容器采集场景和数据完整性要求。下面我们举例几个典型的作业容器采集场景,并给出推荐的采集方案。

  典型场景

  短生命周期作业

  如果任务的执行时间较长,比如超过1分钟,那么采集端采集Job容器数据的时间窗口会更大。这时由于采集

方案的容器发现延迟和开始采集

延迟不敏感,所以DaemonSet采集

方式不会有问题。但是当Job的生命周期小于1分钟时,默认的采集参数可能会导致日志丢失。当Job容器的生命周期超过10秒时,我们可以继续使用DaemonSet的采集方案,只需要调整一些参数即可保证数据采集的完整性。由于标准输出采集原理与容器文件不同,需要调整的参数也不完全相同。通过调整启动参数(全局有效)docker_config_update_interval来减少发现容器后的有效延迟,例如1.0.34版本之前,由默认的10s调整为3s(之后默认为3s)版本),减少容器在发现可能性后无法锁定文件的可能性。调整轮询时间,减少开始采集的延迟,提前锁住文件句柄,防止Pod删除后数据无法采集。标准输出需要调整采集配置(本地采集配置生效),参数名称为FlushIntervalMs,例如从默认的3000ms调整为1000ms;文件采集需要调整启动参数(全局有效),参数名称为max_docker_config_update_times,例如从默认的3分钟频率控制10次调整为60次。如果作业启动时打印大量日志,可以在找到文件后调整采集

文件的位置以防止由于文件未在文件的起始位置启动而导致日志丢失。标准输出需要调整采集配置(本地采集配置生效),参数名StartLogMaxOffset,例如从默认的131072 B调整为13107200 B;文件采集需要调整采集配置(部分采集配置生效),参数名称tail_size_kb,例如从默认的1024KB调整为10240KB。检查工作完成后,不会立即清理,也就是说,刚刚退出的容器的标准输出日志仍然是可读的。如果使用内置的CronJob调度器,确认CronJob的.spec.successfulJobsHistoryLimit和.spec.failedJobsHistoryLimit没有配置或者>0;如果使用自定义调度器,确认Job的.spec.ttlSecondsAfterFinished没有配置或者>0,其自身的逻辑不会立即清理完成的Job。示例 DaemonSet 补丁如下:Job的ttlSecondsAfterFinished没有配置或者>0,它自己的逻辑不会立即清理完成的Job。示例 DaemonSet 补丁如下:Job的ttlSecondsAfterFinished没有配置或者>0,它自己的逻辑不会立即清理完成的Job。示例 DaemonSet 补丁如下:

  spec: template: spec: containers: - name: logtail env: - name: docker_config_update_interval # 减小容器发现延时 value: "3" - name: max_docker_config_update_times # 提高容器配置加载频率,减小开始采集延时 value: "60"

  kubectl patch ds logtail-ds -n kube-system --patch-file ds-patch.yaml

  示例容器标准输入集合配置如下:

  { "inputs": [ { "detail": { "FlushIntervalMs": 1000 # 加快插件轮询频率,减小开始采集延时 }, "type": "service_docker_stdout" } ]}

  在几秒钟内退休工作

  如果容器的生命周期极短,不到10秒,甚至秒退,那么使用DaemonSet的方式很容易因为不可避免的容器发现延迟而导致此类作业容器的数据采集丢失。对于这种情况,我们推荐使用以下两种方法之一: 1. 使用容器的标准输出。容器日志输出转换为使用标准输出,日志轮转由 kubelet 处理。K8s的垃圾回收机制通常可以保证每个Pod都保留最新容器的容器元数据和标准输出日志记录,这样即使容器已经退出,只要Pod不被删除,仍然可以找到容器及其标准输出采集

的日志。如果您采用此解决方案,

  2.使用SideCar或ECI采集,保证数据采集的完整性。不同于普通容器日志的采集,Job容器使用Sidecar采集日志时需要注意退出机制。普通容器的退出通常是由controller发起请求Pod退出,所以Pod中的所有容器都会收到sigterm信号。但是作业容器通常在任务执行完成后会自动退出,采集容器不会收到sigterm信号,所以需要业务容器通知它退出。一种简单的方法是通过共享卷上的文件进行通知。

  示例边车容器文件采集

配置

  

" />

  apiVersion: batch/v1kind: Jobmetadata: name: sidecar-demo namespace: defaultspec: ttlSecondsAfterFinished: 90 template: metadata: name: sidecar-demo spec: restartPolicy: Never containers: - name: nginx-log-demo image: registry.cn-hangzhou.aliyuncs.com/log-service/docker-log-test:latest command: ["/bin/sh", "-c"] args: - /bin/mock_log --log-type=nginx --stdout=false --stderr=true --path=/var/log/nginx/access.log --total-count=10 --logs-per-sec=10; retcode=$?; touch /graveyard/tombstone; exit $retcode volumeMounts: - name: nginx-log mountPath: /var/log/nginx - mountPath: /graveyard name: graveyard ##### logtail sidecar container - name: logtail # more info: https://cr.console.aliyun.com/repository/cn-hangzhou/log-service/logtail/detail # this images is released for every region image: registry.cn-huhehaote.aliyuncs.com/log-service/logtail:latest command: ["/bin/sh", "-c"] args: - /etc/init.d/ilogtaild start; sleep 10; until [[ -f /graveyard/tombstone ]]; do sleep 3; done; /etc/init.d/ilogtaild stop; livenessProbe: exec: command: - /etc/init.d/ilogtaild - status initialDelaySeconds: 30 periodSeconds: 30 resources: limits: memory: 512Mi requests: cpu: 10m memory: 30Mi env: ##### base config # user id - name: ALIYUN_LOGTAIL_USER_ID value: "1654218965343050" # user defined id - name: ALIYUN_LOGTAIL_USER_DEFINED_ID value: hhht-ack-containerd-sidecar # config file path in logtail's container - name: ALIYUN_LOGTAIL_CONFIG value: /etc/ilogtail/conf/cn-huhehaote/ilogtail_config.json ##### env tags config - name: ALIYUN_LOG_ENV_TAGS value: _pod_name_|_pod_ip_|_namespace_|_node_name_|_node_ip_ - name: _pod_name_ valueFrom: fieldRef: fieldPath: metadata.name - name: _pod_ip_ valueFrom: fieldRef: fieldPath: status.podIP - name: _namespace_ valueFrom: fieldRef: fieldPath: metadata.namespace - name: _node_name_ valueFrom: fieldRef: fieldPath: spec.nodeName - name: _node_ip_ valueFrom: fieldRef: fieldPath: status.hostIP volumeMounts: - name: nginx-log mountPath: /var/log/nginx - mountPath: /graveyard name: graveyard ##### share this volume volumes: - name: nginx-log emptyDir: {} - name: graveyard emptyDir: medium: Memory

  本示例配置中,业务容器通过/graveyard/tombstone文件通知采集容器退出,采集容器将元信息暴露给env,以便iLogtail获取容器元信息进行日志标记。一些值得注意的细节如下:

  无论业务容器成功与否,都必须通知获取容器退出:参见下面代码汇总的第2-4行。

   - /bin/mock_log --log-type=nginx --stdout=false --stderr=true --path=/var/log/nginx/access.log --total-count=10 --logs-per-sec=10; retcode=$?; touch /graveyard/tombstone; exit $retcode

  2.采集

容器必须等待至少10秒后才能退出:见下面代码的第2行。这是因为iLogtail启动后,需要从服务端拉取采集配置。如果过早退出,可能会因为没有及时获取采集配置而导致采集数据丢失。

   - /etc/init.d/ilogtaild start; sleep 10; until [[ -f /graveyard/tombstone ]]; do sleep 3; done; /etc/init.d/ilogtaild stop;

  3、容器元信息标记方法:通过ALIYUN_LOG_ENV_TAGS告诉iLogtail标记需要的环境变量,使用"|" 分隔多个环境变量。提到的环境变量可以通过valueFrom引用容器元信息的值。

   - name: ALIYUN_LOG_ENV_TAGS value: _pod_name_|_pod_ip_|_namespace_|_node_name_|_node_ip_ - name: _pod_name_ valueFrom: fieldRef: fieldPath: metadata.name

  采集效果如下:

  ECI 容器文件获取配置示例

  apiVersion: log.alibabacloud.com/v1alpha1kind: AliyunLogConfigmetadata: # 设置资源名,在当前Kubernetes集群内唯一。 name: eci-demospec: # 设置Logstore名称。如果您所指定的Logstore不存在,日志服务会自动创建。 logstore: eci-demo # 设置Logtail采集配置。 logtailConfig: # 设置采集的数据源类型。采集标准输出时,需设置为plugin。 inputType: file # 设置采集的数据源类型。 configName: eci-demo # 设置Logtail配置名称,与资源名(metadata.name)保持一致。 inputDetail: # 设置Logtail采集配置的详细信息。 # 指定通过完整正则模式采集容器文本日志。 logType: common_reg_log # 设置日志文件所在路径。 logPath: /var/log/nginx # 设置日志文件的名称。支持通配符星号(*)和半角问号(?),例如log_*.log。 filePattern: access.log # 设置用于匹配日志行首的行首正则表达式。如果为单行模式,设置成'.*'。 logBeginRegex: '.*' # 设置正则表达式,用于提取日志内容。请根据实际情况设置。 regex: '(\S+)\s(\S+)\s\S+\s\S+\s"(\S+)\s(\S+)\s+([^"]+)"\s+(\S+)\s(\S+)\s(\d+)\s(\d+)\s(\S+)\s"([^"]+)"\s.*' # 设置提取的字段列表。 key : ["time", "ip", "method", "url", "protocol", "latency", "payload", "status", "response-size", "user-agent"]

  使用CRD方式采集

配置更加灵活,基本可以在控制台实现所有的配置能力。inputType支持文件或插件作为输入类型,inputDetail支持多种文本格式配置,允许级联插件配置采集

或处理日志。具体配置请参考帮助文档。

  爆出大量 Job

  爆破大量作业的挑战在于短时间内需要采集

大量的数据,因此采集

容器的压力会突然变大,需要更大的资源上限。对于客户端,建议增加iLogtail的配置参数和容器的资源限制:

  spec: template: spec: containers: - name: logtail resources: limits: cpu: 4000M memory: 4096Mi requests: cpu: 10M memory: 30Mi env: - name: cpu_usage_limit value: "9" - name: mem_usage_limit value: "4096" - name: max_bytes_per_sec value: "209715200" - name: send_request_concurrency value: "80" - name: process_thread_count # 会牺牲SLS上下文功能 value: "8"

  这些参数的含义请参考帮助文档。注意process_thread_count > 1会破坏SLS日志上下文浏览功能,只有设置了其他参数,仍然赶不上数据时才会使用。服务器端建议扩容LogStore的shard,确认容量是否足够。分片数量可以通过峰值流量/5M/s来计算。如果采集时写入速度慢,可以使用Cloud Lens for SLS查看服务器配额是否满。

  概括

  下表总结了上述三种场景以及对应的采集方案:

  场景元素

  推荐计划

  作业生命周期 > 1 分钟

  守护进程集

  作业生命周期 > 10 秒

  DaemonSet + 调参

  工作生命周期

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线