k8s实战之ELK日志管理

首先查看总体流程

首先创建namespace

apiVersion: v1
kind: Namespace
metadata:name: kube-logging

一、首先创建es.yaml 

--- 
apiVersion: v1    #kubernetes API版本,采用最新版本v1
kind: Service  #资源类型定义为Service
metadata: name: elasticsearch-logging  # 服务名称elasticsearch-loggingnamespace: kube-logging   #命名空间为kube-logginglabels:   #标签,用于服务选择器匹配k8s-app: elasticsearch-logging kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "Elasticsearch" 
spec: 
# 定义用于访问 Elasticsearch 的端口ports:- port: 9200protocol: TCPtargetPort: db
# 定义用于标识应属于此服务的 Pod 的选择器selector:k8s-app: elasticsearch-logging 
--- 
# RBAC authn and authz 
apiVersion: v1 
# ServiceAccount 定义用于 Elasticsearch 日志记录
kind: ServiceAccount 
metadata: name: elasticsearch-logging namespace: kube-logging labels: k8s-app: elasticsearch-logging kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile 
---
#用于授予用户对集群中的所有资源的访问权限,Role只对命名空间级别
kind: ClusterRole 
apiVersion: rbac.authorization.k8s.io/v1 
metadata: name: elasticsearch-logging labels: k8s-app: elasticsearch-logging kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile 
rules: 
- apiGroups: - ""
#resources 字段指定了规则适用于哪些资源类型resources: - "services" - "namespaces" - "endpoints"
#verbs 字段指定了规则允许执行的操作  verbs: - "get" 
---
#ClusterRoleBinding 用于将 ClusterRole 绑定到用户或组 
kind: ClusterRoleBinding 
apiVersion: rbac.authorization.k8s.io/v1 
metadata: namespace: kube-logging name: elasticsearch-logging labels: k8s-app: elasticsearch-logging kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile
#以下说明给ServiceAccount授予在ClusterRole中定义的权限
subjects: 
- kind: ServiceAccount  #指定角色绑定的实体类型name: elasticsearch-logging namespace: kube-logging apiGroup: "" 
roleRef: kind: ClusterRole name: elasticsearch-logging apiGroup: "" 
--- 
# Elasticsearch deployment itself 
apiVersion: apps/v1 
kind: StatefulSet #使用statefulset创建Pod 
metadata: name: elasticsearch-logging #pod名称,使用statefulSet创建的Pod是有序号有顺序的 namespace: kube-logging  #命名空间 labels: k8s-app: elasticsearch-logging kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile srv: srv-elasticsearch 
spec: serviceName: elasticsearch-logging #与svc相关联,这可以确保使用以下DNS地址访问Statefulset中的每个pod (es-cluster-[0,1,2].elasticsearch.elk.svc.cluster.local) replicas: 1 #副本数量,单节点
#selector用于指定 StatefulSet 的 Pod 选择器,只有拥有k8s-app的labels才能被匹配selector: matchLabels: k8s-app: elasticsearch-logging #和pod template配置的labels相匹配 template: metadata: labels: k8s-app: elasticsearch-logging kubernetes.io/cluster-service: "true" spec:
#表示这个pod使用serviceAccount的名字   serviceAccountName: elasticsearch-logging containers: - image: docker.io/library/elasticsearch:7.9.3 name: elasticsearch-logging resources: # need more cpu upon initialization, therefore burstable class limits: cpu: 1000m memory: 2Gi requests: cpu: 100m memory: 500Mi ports: - containerPort: 9200 name: db protocol: TCP - containerPort: 9300 name: transport protocol: TCP volumeMounts: - name: elasticsearch-logging mountPath: /usr/share/elasticsearch/data/   #挂载点 env: - name: "NAMESPACE" valueFrom: fieldRef: fieldPath: metadata.namespace - name: "discovery.type"  #定义单节点类型 value: "single-node" - name: ES_JAVA_OPTS #设置Java的内存参数,可以适当进行加大调整 value: "-Xms512m -Xmx2g"  volumes: - name: elasticsearch-logging hostPath: path: /data/es/ nodeSelector: #如果需要匹配落盘节点可以添加 nodeSelect es: data tolerations: - effect: NoSchedule operator: Exists # Elasticsearch requires vm.max_map_count to be at least 262144. # If your OS already sets up this number to a higher value, feel free # to remove this init container. initContainers: #容器初始化前的操作 - name: elasticsearch-logging-init image: alpine:3.6 command: ["/sbin/sysctl", "-w", "vm.max_map_count=262144"] #添加mmap计数限制,太低可能造成内存不足的错误 securityContext:  #仅应用到指定的容器上,并且不会影响Volume privileged: true #运行特权容器 - name: increase-fd-ulimit image: busybox imagePullPolicy: IfNotPresent command: ["sh", "-c", "ulimit -n 65536"] #修改文件描述符最大数量 securityContext: privileged: true - name: elasticsearch-volume-init #es数据落盘初始化,加上777权限 image: alpine:3.6 command: - chmod - -R - "777" - /usr/share/elasticsearch/data/ volumeMounts: - name: elasticsearch-logging mountPath: /usr/share/elasticsearch/data/

 二、创建logstach.yaml

--- 
apiVersion: v1 
kind: Service  #指定了资源的类型,这里是 Service,用于定义服务的属性
metadata: #包含资源的元数据,如名称、命名空间等。name: logstash namespace: kube-logging 
spec: #包含服务的规格,定义了如何创建和运行服务。ports: #指定了服务暴露的端口- port: 5044 #服务监听的端口号targetPort: beats #将服务请求转发到的 Pod 的端口。   selector: #指定了 Pod 的标签选择器,用于匹配需要访问该服务的 Pod type: logstash #匹配的标签。clusterIP: None  #设置为 None 表示这是一个无头服务(Headless Service),它不会创建一个虚拟 IP,而是直接将流量转发到匹配的 Pod
--- 
apiVersion: apps/v1 
kind: Deployment  #定义了一个 Deployment,用于管理 Pod 的生命周期和副本数。
metadata:  #包含 Deployment 的元数据name: logstash namespace: kube-logging 
spec: selector: matchLabels: type: logstash template: metadata: labels: type: logstash srv: srv-logstash spec: containers: - image: docker.io/kubeimages/logstash:7.9.3 #该镜像支持arm64和amd64两种架构 name: logstash ports: - containerPort: 5044 name: beats command: - logstash - '-f' - '/etc/logstash_c/logstash.conf' env: - name: "XPACK_MONITORING_ELASTICSEARCH_HOSTS" value: "http://elasticsearch-logging:9200" volumeMounts: - name: config-volume mountPath: /etc/logstash_c/ - name: config-yml-volume mountPath: /usr/share/logstash/config/ - name: timezone mountPath: /etc/localtime resources: #logstash一定要加上资源限制,避免对其他业务造成资源抢占影响 limits: cpu: 1000m memory: 2048Mi requests: cpu: 512m memory: 512Mi volumes: - name: config-volume configMap: name: logstash-conf items: - key: logstash.conf path: logstash.conf - name: timezone hostPath: path: /etc/localtime - name: config-yml-volume configMap: name: logstash-yml items: - key: logstash.yml path: logstash.yml --- 
apiVersion: v1 
kind: ConfigMap 
metadata: name: logstash-conf namespace: kube-logging labels: type: logstash 
data: logstash.conf: |- input {beats { port => 5044 } } filter {# 处理 ingress 日志 if [kubernetes][container][name] == "nginx-ingress-controller" {json {source => "message" target => "ingress_log" }if [ingress_log][requesttime] { mutate { convert => ["[ingress_log][requesttime]", "float"] }}if [ingress_log][upstremtime] { mutate { convert => ["[ingress_log][upstremtime]", "float"] }} if [ingress_log][status] { mutate { convert => ["[ingress_log][status]", "float"] }}if  [ingress_log][httphost] and [ingress_log][uri] {mutate { add_field => {"[ingress_log][entry]" => "%{[ingress_log][httphost]}%{[ingress_log][uri]}"} } mutate { split => ["[ingress_log][entry]","/"] } if [ingress_log][entry][1] { mutate { add_field => {"[ingress_log][entrypoint]" => "%{[ingress_log][entry][0]}/%{[ingress_log][entry][1]}"} remove_field => "[ingress_log][entry]" }} else { mutate { add_field => {"[ingress_log][entrypoint]" => "%{[ingress_log][entry][0]}/"} remove_field => "[ingress_log][entry]" }}}}# 处理以srv进行开头的业务服务日志 if [kubernetes][container][name] =~ /^srv*/ { json { source => "message" target => "tmp" } if [kubernetes][namespace] == "kube-logging" { drop{} } if [tmp][level] { mutate{ add_field => {"[applog][level]" => "%{[tmp][level]}"} } if [applog][level] == "debug"{ drop{} } } if [tmp][msg] { mutate { add_field => {"[applog][msg]" => "%{[tmp][msg]}"} } } if [tmp][func] { mutate { add_field => {"[applog][func]" => "%{[tmp][func]}"} } } if [tmp][cost]{ if "ms" in [tmp][cost] { mutate { split => ["[tmp][cost]","m"] add_field => {"[applog][cost]" => "%{[tmp][cost][0]}"} convert => ["[applog][cost]", "float"] } } else { mutate { add_field => {"[applog][cost]" => "%{[tmp][cost]}"} }}}if [tmp][method] { mutate { add_field => {"[applog][method]" => "%{[tmp][method]}"} }}if [tmp][request_url] { mutate { add_field => {"[applog][request_url]" => "%{[tmp][request_url]}"} } }if [tmp][meta._id] { mutate { add_field => {"[applog][traceId]" => "%{[tmp][meta._id]}"} } } if [tmp][project] { mutate { add_field => {"[applog][project]" => "%{[tmp][project]}"} }}if [tmp][time] { mutate { add_field => {"[applog][time]" => "%{[tmp][time]}"} }}if [tmp][status] { mutate { add_field => {"[applog][status]" => "%{[tmp][status]}"} convert => ["[applog][status]", "float"] }}}mutate { rename => ["kubernetes", "k8s"] remove_field => "beat" remove_field => "tmp" remove_field => "[k8s][labels][app]" }}output { elasticsearch { hosts => ["http://elasticsearch-logging:9200"] codec => json index => "logstash-%{+YYYY.MM.dd}" #索引名称以logstash+日志进行每日新建 }} 
---apiVersion: v1 
kind: ConfigMap 
metadata: name: logstash-yml namespace: kube-logging labels: type: logstash 
data: logstash.yml: |- http.host: "0.0.0.0" xpack.monitoring.elasticsearch.hosts: http://elasticsearch-logging:9200

三、创建filebeat.yaml

--- 
apiVersion: v1 
kind: ConfigMap #定义了一个 ConfigMap,用于存储 Filebeat 的配置文件
metadata: #包含 ConfigMap 的元数据name: filebeat-config namespace: kube-logging labels: k8s-app: filebeat  #用于标识 ConfigMap 的标签。
data: filebeat.yml: |-  #Filebeat 的配置文件内容filebeat.inputs:  #定义了 Filebeat 的输入源- type: container  #输入类型为容器enable: true  #启用容器输入paths: - /var/log/containers/*.log #这里是filebeat采集挂载到pod中的日志目录 processors: - add_kubernetes_metadata: #添加k8s的字段用于后续的数据清洗 host: ${NODE_NAME}   #使用节点名称作为主机名matchers: - logs_path: logs_path: "/var/log/containers/"  #指定日志路径#output.kafka:  #如果日志量较大,es中的日志有延迟,可以选择在filebeat和logstash中间加入kafka #  hosts: ["kafka-log-01:9092", "kafka-log-02:9092", "kafka-log-03:9092"] # topic: 'topic-test-log' #  version: 2.0.0 output.logstash: #因为还需要部署logstash进行数据的清洗,因此filebeat是把数据推到logstash中 hosts: ["logstash:5044"]  #Logstash 服务的地址和端口enabled: true   #启用 Logstash 输出
--- 
apiVersion: v1 
kind: ServiceAccount  #定义了一个 ServiceAccount,用于运行 Filebeat Pod
metadata: #包含 ServiceAccount 的元数据name: filebeat  namespace: kube-logging labels:   #用于标识 ServiceAccount 的标签。k8s-app: filebeat
--- 
apiVersion: rbac.authorization.k8s.io/v1   #定义了一个 ClusterRole,用于授予 ServiceAccount 权限。
kind: ClusterRole 
metadata: name: filebeat labels: k8s-app: filebeat 
rules:  #定义了 ClusterRole 的规则。
- apiGroups: [""] # "" indicates the core API group resources:   #指定资源- namespaces - pods verbs: ["get", "watch", "list"]  #指定操作
--- 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding  #将 ClusterRole 绑定到 ServiceAccount
metadata: name: filebeat 
subjects:  #定义了 ClusterRoleBinding 的主体。
- kind: ServiceAccount  #主体类型为 ServiceAccountname: filebeat namespace: kube-logging 
roleRef: kind: ClusterRole #引用了 ClusterRolename: filebeat  #引用的 ClusterRole 名称apiGroup: rbac.authorization.k8s.io 
--- 
apiVersion: apps/v1 
kind: DaemonSet  #定义了一个 DaemonSet,用于确保在每个节点上运行一个 Filebeat Pod。
metadata: name: filebeat  #包含 DaemonSet 的元数据。namespace: kube-logging labels: k8s-app: filebeat  #用于标识 DaemonSet 的标签
spec:  #包含 DaemonSet 的规格selector:  #定义了 DaemonSet 的选择器。matchLabels: k8s-app: filebeat template:  #定义了 Pod 的模板。metadata: labels: k8s-app: filebeat spec: serviceAccountName: filebeat terminationGracePeriodSeconds: 30 containers: - name: filebeat image: docker.io/kubeimages/filebeat:7.9.3 #该镜像支持arm64和amd64两种架构 args: [ "-c", "/etc/filebeat.yml", "-e","-httpprof","0.0.0.0:6060" ] #ports: #  - containerPort: 6060 #    hostPort: 6068 env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: ELASTICSEARCH_HOST value: elasticsearch-logging - name: ELASTICSEARCH_PORT value: "9200" securityContext: runAsUser: 0 # If using Red Hat OpenShift uncomment this: #privileged: true resources: limits: memory: 1000Mi cpu: 1000m requests: memory: 100Mi cpu: 100m volumeMounts: - name: config #挂载的是filebeat的配置文件 mountPath: /etc/filebeat.yml readOnly: true subPath: filebeat.yml - name: data #持久化filebeat数据到宿主机上 mountPath: /usr/share/filebeat/data - name: varlibdockercontainers #这里主要是把宿主机上的源日志目录挂载到filebeat容器中,如果没有修改docker或者containerd的runtime进行了标准的日志落盘路径,可以把mountPath改为/var/lib mountPath: /var/libreadOnly: true - name: varlog #这里主要是把宿主机上/var/log/pods和/var/log/containers的软链接挂载到filebeat容器中 mountPath: /var/log/ readOnly: true - name: timezone mountPath: /etc/localtime volumes: - name: config configMap: defaultMode: 0600 name: filebeat-config - name: varlibdockercontainers hostPath: #如果没有修改docker或者containerd的runtime进行了标准的日志落盘路径,可以把path改为/var/lib path: /var/lib- name: varlog hostPath: path: /var/log/ # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart - name: inputs configMap: defaultMode: 0600 name: filebeat-inputs - name: data hostPath: path: /data/filebeat-data type: DirectoryOrCreate - name: timezone hostPath: path: /etc/localtime tolerations: #加入容忍能够调度到每一个节点 - effect: NoExecute key: dedicated operator: Equal value: gpu - effect: NoSchedule operator: Exists 

四、创建kibana.yaml

---
apiVersion: v1
kind: ConfigMap
metadata:namespace: kube-loggingname: kibana-configlabels:k8s-app: kibana
data:   #包含 ConfigMap 中的数据。kibana.yml: |-   #Kibana 的配置文件内容server.name: kibanaserver.host: "0"              			#允许 Kibana 监听所有网络接口i18n.locale: zh-CN                      #设置默认语言为中文elasticsearch:hosts: ${ELASTICSEARCH_HOSTS}         #es集群连接地址,由于我这都都是k8s部署且在一个ns下,可以直接使用service name连接
--- 
apiVersion: v1 
kind: Service  #用于公开 Kibana 服务。
metadata: name: kibana namespace: kube-logging labels: k8s-app: kibana kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "Kibana" srv: srv-kibana 
spec:  #包含 Service 的规格。type: NodePort  #Service 类型为 NodePort,允许外部通过节点的 IP 和端口访问服务ports: - port: 5601 protocol: TCP targetPort: ui selector:   #定义了 Service 的选择器。k8s-app: kibana 
--- 
apiVersion: apps/v1 
kind: Deployment   #定义了一个 Deployment,用于管理 Kibana Pod 的生命周期和副本数。
metadata: name: kibana namespace: kube-logging labels: k8s-app: kibana kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile srv: srv-kibana 
spec:   #包含 Deployment 的规格replicas: 1 selector: matchLabels: k8s-app: kibana template:   #定义了 Pod 的模板。metadata: labels: k8s-app: kibana spec: containers: - name: kibana image: docker.io/kubeimages/kibana:7.9.3 #该镜像支持arm64和amd64两种架构 resources: # need more cpu upon initialization, therefore burstable class limits: cpu: 1000m requests: cpu: 100m env: - name: ELASTICSEARCH_HOSTS value: http://elasticsearch-logging:9200 ports: - containerPort: 5601 name: ui protocol: TCP volumeMounts:- name: configmountPath: /usr/share/kibana/config/kibana.ymlreadOnly: truesubPath: kibana.ymlvolumes:- name: configconfigMap:name: kibana-config
--- 
apiVersion: networking.k8s.io/v1
kind: Ingress #定义了一个 Ingress,用于将外部 HTTP/HTTPS 流量路由到内部服务。
metadata: name: kibana namespace: kube-logging 
spec: ingressClassName: nginxrules: - host: kibana.wolfcode.cnhttp: paths: - path: / pathType: Prefixbackend: service:name: kibana port:number: 5601 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/225012.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时间Date

你有没有思考过时间问题: 前端为什么可以直接看见时间格式的数据 后端怎么接受的数据,怎么处理的 一般来说:前端传输来数据都是时间格式的字符串,那么后端需要能够解析时间格式的字符串,归功于JSONFormat ,可以解析…

LED靠近语音声光警示灯

应用范围: 适用于高压线塔、施工工地、铁路道口等危险区域。通过微波感应检测人体行动,触发语音警报,做到提前预警,避免可能发生的危险事故。 产品特点 1:设备采用独立太阳能供电系统,警示灯与语音报警装置均为太阳能独立供电&…

【Linux驱动】最基本的驱动框架 | LED驱动

🐱作者:一只大喵咪1201 🐱专栏:《Linux驱动》 🔥格言:你只管努力,剩下的交给时间! 目录 🏀最基本的驱动框架⚽驱动程序框架⚽编程 🏀LED驱动⚽配置GPIO⚽编程…

智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.向量加权平均算法4.实验参数设定…

uniapp创建/运行/发布项目

1、产生背景----跨平台应用框架 在移动端各大App盛行的时代,App之间的竞争也更加激烈,他们执着于让一个应用可以做多个事情 所以就应运而生了小程序,微信小程序、支付宝小程序、抖音小程序等等基于App本身的内嵌类程序。 但是各大App他不可…

【ARMv8M Cortex-M33 系列 1 -- SAU 介绍】

文章目录 Cortex-M33 SAU 介绍SAU 的主要功能包括SAU 寄存器配置示例 Cortex-M33 SAU 介绍 在 ARMv8-M 架构中,SAU(Security Attribution Unit)是安全属性单元,用于配置和管理内存区域的安全属性。SAU 是 ARM TrustZone 技术的一…

JavaScript中的prototype和_proto_的关系是什么

JavaScript中的prototype和_proto_的关系是什么 __proto__ 是 JavaScript 中对象的一个内部属性,它指向该对象的原型。JavaScript 中每个对象都有一个 __proto__ 属性,通过它可以访问对象的原型。prototype 是函数对象特有的属性,每个函数都…

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错的问题

目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,找出出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总(专栏文章列表&…

Apache RocketMQ,构建云原生统一消息引擎

本文整理于 2023 年云栖大会林清山带来的主题演讲《Apache RocketMQ 云原生统一消息引擎》 演讲嘉宾: 林清山(花名:隆基),Apache RocketMQ 联合创始人,阿里云资深技术专家,阿里云消息产品线负…

正则表达式:元字符

一、什么事元字符 正则是由一系列的元字符组成的,所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,元字符是构成正则表达式的基本元件。 二、元字符的分类 1.特殊单字符 表达式含义\d匹配任意一个数字\D匹配任意非数字\w匹配任意一个字母、…

.NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布

作者: Jon Galloway - Principal Program Manager, .NET Community Team Mehul Harry - Product Marketing Manager, .NET, Azure Marketing 排版:Alan Wang .NET Conf 2023 是有史以来规模最大的 .NET 会议,来自全球各地的演讲者进行了 100 …

3分钟了解安全数据交换系统有什么用!

企业为了保护核心数据安全,都会采取一些措施,比如做网络隔离划分,分成了不同的安全级别网络,或者安全域,接下来就是需要建设跨网络、跨安全域的安全数据交换系统,将安全保障与数据交换功能有机整合在一起&a…

掌握ElasticSearch(一):Elasticsearch安装与配置、Kibana安装

文章目录 〇、简介1.Elasticsearch简介2.典型业务场景3.数据采集工具4.名词解释 一、安装1.使用docker(1)创建虚拟网络(2)Elasticsearch安装步骤 2.使用压缩包 二、配置1.目录介绍2.配置文件介绍3.elasticsearch.yml节点配置4.jvm.options堆配置 二、可视化工具Kibana1.介绍2.安…

算法leetcode|94. 二叉树的中序遍历(多语言实现)

文章目录 94. 二叉树的中序遍历:样例 1:样例 2:样例 3:提示: 分析:题解:rust:go:c:python:java: 94. 二叉树的中序遍历: …

51单片机相关寄存器

前言 单片机复习的时候对应寄存器的记忆感觉很混乱,这里进行一下整理,后面的单词是我用来辅助记忆的,可能并不是表示原本的含义。 P3口的第二功能 0RXD 串行数据输入口 1TXD串行数据输出口2INT0外部中断0输入3INT1外部中断1输入4T0定时器0外部计数输入…

2023新能源汽车,吵得越凶,卖得越多

作者 | 辰纹 来源 | 洞见新研社 2023年的汽车行业很残酷,合资大败退,市场份额被自主品牌大幅渗透,三菱退出中国市场,成为真实写照。 新能源车企,威马领头,天际、自游家NIUTRON、恒驰、爱驰、雷丁等造车新…

【大厂面试】之 美团(一面经含答案)

美团 一面 tcp三次握手,四次挥手。time-wait、close-wait状态。MSL代表什么?为什么time-wait是2MSL,可不可以更长?如果不设置time-wait有什么影响 time-wait是主动关闭方的一个状态;close-wait是被动关闭方的一个状态…

贪吃蛇小游戏的代码实现之知识点铺垫篇

今天给大家介绍一个很经典的小游戏,它和扫雷在经典小游戏这方面可以说是旗鼓相当,它的名字就是贪吃蛇。贪吃蛇游戏最初为单机模式,后续又陆续推出团战模式、赏金模式、挑战模式等多种玩法。该游戏具体玩法是:用游戏把子上下左右控…

地域与文化,智能酒精壁炉选择的多元因素

不同地域和文化背景常常会影响人们的各种选择,尤其是对智能酒精壁炉的选择上,更会受到地域气候、文化传统以及个人审美等多方面因素的影响,下面将探讨不同地域和文化在智能酒精壁炉选择上的独特理由。 在寒冷地区,人们会更倾向于选…

【Filament】纹理贴图

1 前言 本文主要介绍使用 Filament 实现纹理贴图,读者如果对 Filament 不太熟悉,请回顾以下内容。 Filament环境搭建绘制三角形绘制矩形绘制圆形绘制立方体 Filament 纹理坐标的 x、y 轴正方向分别朝右和朝上,其 y 轴正方向朝向与 OpenGL ES…