Kubernetes平台部署Grafana Loki Promtail系统

news2024/11/22 16:45:48

部署结构图:
在这里插入图片描述

  • Loki 是主服务,负责存储日志和处理查询
  • promtail 是代理,负责收集日志并将其发送给 loki
  • Grafana 用于 UI 展示

只要在应用程序服务器上安装promtail来收集日志然后发送给Loki存储,就可以在Grafana UI界面通过添加Loki为数据源进行日志查询(如果Loki服务器性能不够,可以部署多个Loki进行存储及查询)。作为一个日志系统不光只有查询分析日志的能力,还能对日志进行监控和报警。

文章目录

  • 一、创建独立的命名空间
  • 二、部署Grafana
    • 2.1 编写grafana部署的配置文件
    • 2.2 部署grafana
  • 三、部署 Loki
    • 3.1 编写Loki部署的配置文件
    • 3.2 部署 Loki
  • 四、部署 promtail
    • 4.1 编写配置文件
    • 4.2 部署 Promtail
  • 五、检查部署结果
    • 5.1 Kubernetes后台检查Pod部署状态
    • 5.2 浏览器打开grafana界面如下,表示OK

一、创建独立的命名空间

为日志系统创建一个独立的命令空间

kubectl create ns logging

二、部署Grafana

2.1 编写grafana部署的配置文件

创建 grafana 目录,并在目录中创建 grafana-deploy.yaml 文件,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  labels:
    app: grafana
  namespace: logging
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:8.4.7
        imagePullPolicy: IfNotPresent
        securityContext:
          runAsUser: 0
        env:
        - name: GF_AUTH_BASIC_ENABLED
          value: "true"
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "false"
#        resources:
#          requests:
#            cpu: 100m
#            memory: 200Mi
#          limits:
#            cpu: '1'
#            memory: 2Gi
        readinessProbe:
          httpGet:
            path: /login
            port: 3000
        volumeMounts:
        - name: storage
          mountPath: /var/lib/grafana
      volumes:
      - name: storage
        hostPath:
          path: /hostpath/grafana
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
  labels:
    app: grafana
  namespace: logging
spec:
  type: NodePort
  ports:
  - port: 3000
    targetPort: 3000
    nodePort: 30200
  selector:
    app: grafana

上述配置修改注意点:
(1)上述有两处namespace,此处需要使用步骤一中创建的命名空间,这里是logging
在这里插入图片描述
(2)挂载的目录需要在服务器上创建并且设置为足够的访问权限,比如这里:

mkdir -p /hostpath/grafana
chmod 777 -R /hostpath/grafana
在这里插入图片描述

(3)对外开发端口可以自行设置,这里比如 30200

在这里插入图片描述

2.2 部署grafana

进入grafana目录,然后执行部署命令

cd grafana
kubectl apply -f grafana-deploy.yaml

三、部署 Loki

3.1 编写Loki部署的配置文件

创建 loki文件夹,然后再 loki 文件夹中创建三个配置文件,分别是:loki-rbac.yaml、loki-configmap.yaml和loki-statefulset.yaml

loki-rbac.yaml文件内容如下:

apiVersion: v1
kind: Namespace
metadata:
  name: logging
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: loki
  namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: loki
  namespace: logging
rules:
- apiGroups: ["extensions"]
  resources: ["podsecuritypolicies"]
  verbs: ["use"]
  resourceNames: [loki]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: loki
  namespace: logging
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: loki
subjects:
- kind: ServiceAccount
  name: loki

上述配置修改注意点:
(1)只需保证其中的namespace雨步骤一中设置的一致即可,比如都是logging时,此文件不需要修改

在这里插入图片描述
loki-configmap.yaml文件的内容如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: loki
  namespace: logging
  labels:
    app: loki
data:
  loki.yaml: |
    auth_enabled: false
    ingester:
      chunk_idle_period: 3m
      chunk_block_size: 262144
      chunk_retain_period: 1m
      max_transfer_retries: 0
      lifecycler:
        ring:
          kvstore:
            store: inmemory
          replication_factor: 1
    limits_config:
      enforce_metric_name: false
      reject_old_samples: true
      reject_old_samples_max_age: 168h
    schema_config:
      configs:
      - from: "2022-05-15"
        store: boltdb-shipper
        object_store: filesystem
        schema: v11
        index:
          prefix: index_
          period: 24h
    server:
      http_listen_port: 3100
    storage_config:
      boltdb_shipper:
        active_index_directory: /data/loki/boltdb-shipper-active
        cache_location: /data/loki/boltdb-shipper-cache
        cache_ttl: 24h
        shared_store: filesystem
      filesystem:
        directory: /data/loki/chunks
    chunk_store_config:
      max_look_back_period: 0s
    table_manager:
      retention_deletes_enabled: true
      retention_period: 48h
    compactor:
      working_directory: /data/loki/boltdb-shipper-compactor
      shared_store: filesystem

上述配置修改注意点:
(1)namespace同样需要和步骤一中的设置保持一致
在这里插入图片描述
loki-statefulset.yaml文件的内容如下:

apiVersion: v1
kind: Service
metadata:
  name: loki
  namespace: logging
  labels:
    app: loki
spec:
  type: NodePort
  ports:
    - port: 3100
      protocol: TCP
      name: http-metrics
      targetPort: http-metrics
      nodePort: 30201
  selector:
    app: loki
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: loki
  namespace: logging
  labels:
    app: loki
spec:
  podManagementPolicy: OrderedReady
  replicas: 1
  selector:
    matchLabels:
      app: loki
  serviceName: loki
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: loki
    spec:
      serviceAccountName: loki
      initContainers:
      - name: chmod-data
        image: busybox:1.28.4
        imagePullPolicy: IfNotPresent
        command: ["chmod","-R","777","/loki/data"]
        volumeMounts:
        - name: storage
          mountPath: /loki/data
      containers:
        - name: loki
          image: grafana/loki:2.3.0
          imagePullPolicy: IfNotPresent
          args:
            - -config.file=/etc/loki/loki.yaml
          volumeMounts:
            - name: config
              mountPath: /etc/loki
            - name: storage
              mountPath: /data
          ports:
            - name: http-metrics
              containerPort: 3100
              protocol: TCP
          livenessProbe:
            httpGet: 
              path: /ready
              port: http-metrics
              scheme: HTTP
            initialDelaySeconds: 45
          readinessProbe:
            httpGet: 
              path: /ready
              port: http-metrics
              scheme: HTTP
            initialDelaySeconds: 45
          securityContext:
            readOnlyRootFilesystem: true
      terminationGracePeriodSeconds: 4800
      volumes:
        - name: config
          configMap:
            name: loki
        - name: storage
          hostPath:
            path: /app/loki

上述配置修改注意点:
(1)同样,namespace需要和步骤一中设置为一致
(2)设置Loki对外开放的端口,比如这里设置为30201

在这里插入图片描述

3.2 部署 Loki

在loki目录中执行如下命令进行部署

cd loki
kubectl apply -f .

四、部署 promtail

4.1 编写配置文件

首先创建 promtail 文件夹,然后再文件夹中创建 promtail-rbac.yaml、promtail-configmap.yaml和promtail-daemonset.yaml三个文件

promtail-rbac.yaml 文件内容如下,同样,这里不需要修改什么配置,只需要保证namespace和步骤一中创建的一致即可。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: loki-promtail
  labels:
    app: promtail
  namespace: logging
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    app: promtail
  name: promtail-clusterrole
  namespace: logging
rules:
- apiGroups: [""]
  resources: ["nodes","nodes/proxy","services","endpoints","pods"]
  verbs: ["get", "watch", "list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: promtail-clusterrolebinding
  labels:
    app: promtail
  namespace: logging
subjects:
  - kind: ServiceAccount
    name: loki-promtail
    namespace: logging
roleRef:
  kind: ClusterRole
  name: promtail-clusterrole
  apiGroup: rbac.authorization.k8s.io

promtail-configmap.yaml 文件内容如下,此文件同样只需要保证namespace与步骤一中一致即可,不需要做其他修改

apiVersion: v1
kind: ConfigMap
metadata:
  name: loki-promtail
  namespace: logging
  labels:
    app: promtail
data:
  promtail.yaml: |
    client:
      backoff_config:
        max_period: 5m 
        max_retries: 10
        min_period: 500ms
      batchsize: 1048576
      batchwait: 1s
      external_labels: {}
      timeout: 10s
    positions:
      filename: /run/promtail/positions.yaml
    server:
      http_listen_port: 3101
    target_config:
      sync_period: 10s
    scrape_configs:
    - job_name: kubernetes-pods-name
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels:
        - __meta_kubernetes_pod_label_name
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-app
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: .+
        source_labels:
        - __meta_kubernetes_pod_label_name
      - source_labels:
        - __meta_kubernetes_pod_label_app
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-direct-controllers
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: .+
        separator: ''
        source_labels:
        - __meta_kubernetes_pod_label_name
        - __meta_kubernetes_pod_label_app
      - action: drop
        regex: '[0-9a-z-.]+-[0-9a-f]{8,10}'
        source_labels:
        - __meta_kubernetes_pod_controller_name
      - source_labels:
        - __meta_kubernetes_pod_controller_name
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-indirect-controller
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: .+
        separator: ''
        source_labels:
        - __meta_kubernetes_pod_label_name
        - __meta_kubernetes_pod_label_app
      - action: keep
        regex: '[0-9a-z-.]+-[0-9a-f]{8,10}'
        source_labels:
        - __meta_kubernetes_pod_controller_name
      - action: replace
        regex: '([0-9a-z-.]+)-[0-9a-f]{8,10}'
        source_labels:
        - __meta_kubernetes_pod_controller_name
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-static
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: ''
        source_labels:
        - __meta_kubernetes_pod_annotation_kubernetes_io_config_mirror
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_label_component
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_annotation_kubernetes_io_config_mirror
        - __meta_kubernetes_pod_container_name
        target_label: __path__

promtail-daemonset.yaml 配置文件的内容如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: loki-promtail
  namespace: logging
  labels:
    app: promtail
spec:
  selector:
    matchLabels:
      app: promtail
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: promtail
    spec:
      serviceAccountName: loki-promtail
      containers:
        - name: promtail
          image: grafana/promtail:2.3.0
          imagePullPolicy: IfNotPresent
          args: 
          - -config.file=/etc/promtail/promtail.yaml
          - -client.url=http://192.168.16.40:30201/loki/api/v1/push
          env: 
          - name: HOSTNAME
            valueFrom: 
              fieldRef: 
                apiVersion: v1
                fieldPath: spec.nodeName
          volumeMounts:
          - mountPath: /etc/promtail
            name: config
          - mountPath: /run/promtail
            name: run
          - mountPath: /var/lib/docker/containers
            name: docker
            readOnly: true
          - mountPath: /var/log/pods
            name: pods
            readOnly: true
          ports:
          - containerPort: 3101
            name: http-metrics
            protocol: TCP
          securityContext:
            readOnlyRootFilesystem: true
            runAsGroup: 0
            runAsUser: 0
          readinessProbe:
            failureThreshold: 5
            httpGet:
              path: /ready
              port: http-metrics
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
        operator: Exists
      volumes:
        - name: config
          configMap:
            name: loki-promtail
        - name: run
          hostPath:
            path: /run/promtail
            type: ""
        - name: docker
          hostPath:
            path: /var/lib/docker/containers
        - name: pods
          hostPath:
            path: /var/log/pods

上述配置修改注意点:
(1)同样namespace需要与步骤一中的保持一致
(2)如下位置需要修改为步骤三中配置的 Loki 的地址
在这里插入图片描述

4.2 部署 Promtail

进入 promtail 目录,然后执行部署命令即可

cd promtail
kubectl apply -f .

五、检查部署结果

5.1 Kubernetes后台检查Pod部署状态

执行如下命令即可查看pod状态,均为running时表示部署OK

[root@master ~]# kubectl get pod -n logging
NAME                       READY   STATUS    RESTARTS   AGE
grafana-66496d957f-ngq5g   1/1     Running   0          21h
loki-0                     1/1     Running   0          24h
loki-promtail-8vjd6        1/1     Running   0          20h
loki-promtail-gmr5f        1/1     Running   0          20h
loki-promtail-svwtn        1/1     Running   0          20h
loki-promtail-tnvr9        1/1     Running   0          20h
[root@master ~]#

5.2 浏览器打开grafana界面如下,表示OK

比如 192.168.16.40:30200,如下表示部署OK
在这里插入图片描述
Loki数据源
在这里插入图片描述

参考链接:
https://blog.csdn.net/redrose2100/article/details/126851964
https://blog.csdn.net/tianmingqing0806/article/details/126766308

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络工程师回顾学习(第二部分)

第六章:网络互连与互联网 需要掌握: (1)网络互连设备 (2)网络互连的基本原理和关键技术 (扩展:TCP/IP协议簇) (3)Internet协议及其提供的网络…

【python海洋专题四十】海洋指数画法--单色填充图

【python海洋专题四十】海洋指数画法–单色填充图 【python海洋专题四十】海洋指数画法–单色填充图 数据:AMO_index 图像展示: 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【p…

详细记一下jvm调优整过程

cpu占用过高 cpu占用过高要分情况讨论,是不是业务上在搞活动,突然有大批的流量进来,而且活动结束后cpu占用率就下降了,如果是这种情况其实可以不用太关心,因为请求越多,需要处理的线程数越多,这…

解密Elasticsearch:深入探究这款搜索和分析引擎

•开篇 最近使用Elasticsearch实现画像系统,实现的dmp的数据中台能力。同时调研了竞品的架构选型。以及重温了redis原理等。特此做一次es的总结和回顾。网上没看到有人用Elasticsearch来完成画像的。我来做第一次尝试。 背景说完,我们先思考一件事&…

分布式数据库·Hive和MySQL的安装与配置

一、版本要求:Hadoop:hadoop-2.10.1、MySQL:mysql-8.0.35、 HIVE:apache-hive-3.1.2、MySQL驱动:mysql-connector-java-5.1.49 安装包网盘链接:阿里云盘分享 安装位置 Hive:master、MySQL:slave1 二、卸载已安装的…

智能柜+MRO:制造业中的自动售货机

每当谈及企业数字化转型,多数人想到的是人工智能、大数据等高端技术的应用,或是原有业务流程和运营方式的数字化与自动化,实现大幅降本增效等。然而,对于急需在数字时代找到生存之道的企业来说,数字化转型的要求远不止…

如何通过CRM系统进行销售机会管理?

销售机会管理是在销售过程中对潜在客户的精细化管理,销售机会管理的本质是公司用于管理销售机会通用的工具和方法。对于希望建立长期客户关系的现代销售团队来说,CRM客户管理系统是必不可少的工具。那企业如何通过CRM系统进行销售机会管理? …

抖音AAN服务商有几家?

大家都知道抖音服务商多如牛毛,有本地生活服务商,MCN机构服务商,企业认证服务商,ISV服务商等等。但是aan服务商就屈指可数。 aan技术服务商 从关系层面讲,aan服务商的关系友好到啥程度呢,就好比微信指定了…

强强联合!Flat Ads出席云栖大会,加入阿里云“橙”云出海服务联盟

10月31日,一年一度的科技盛会云栖大会在杭州云栖小镇正式开幕。本届云栖大会以“计算,为了无法计算的价值”为主题,除两场重磅主论坛外,还邀请1000多位行业实干家,带来500余场主题分享与互动,通过演讲、研讨…

分享:轰动全球的12大创意二维码营销案例!

今天我们要分享是12个非常有影响力、引起全球轰动的、很成功的创意二维码营销案例。在日常工作中二维码被我们用来存储和分享信息,与此同时,二维码也正在各大展览活动中、电影大片里、全球体育赛事相关活动中、时尚T台上…大展风采,它们帮助品…

Linux内核分析(九)--CPU上下文

目录 一、引言 二、CPU上下文 ------>2.1、CPU上下文切换 三、线程上下文切换 ------>3.1、协程 四、中断上下文切换 ------>4.1、vmstat ------>4.2、pidstat ------>4.3、sysbench 一、引言 Linux是一个多任务的操作系统,可以支持远大于CPU数量的…

数据结构与算法—插入排序选择排序

目录 一、排序的概念 二、插入排序 1、直接插入排序 直接插入排序的特性总结: 2、希尔排序 希尔排序的特性总结: 三、选择排序 1、直接选择排序 时间复杂度 2、堆排序—排升序(建大堆) 向下调整函数 堆排序函数 四、交换排序 1、冒泡排…

vue+css动画 实现文字的上下轮播切换

突然间碰到一个比较丝滑的特效,就研究了一下想把它实现出来。 效果:渐隐消失,底部往上走覆盖出现 以下是完整代码,复制粘贴即可运行 <template><div class="aaa"><divclass="page1":class="{ private-fade-out: prevIndex === 1…

window11安装nvm

链接 默认已经安装了node 没有安装的请看链接 github下载最新nvm https://github.com/coreybutler/nvm-windows/releases 找到github下面的 解压之后 安装exe文件 路径自己选择 配置路径和下载源 找到nvm安装路径 -> 找到 settings.txt 文件 -> 配置下载源 node_m…

CSS 下拉菜单、提示工具、图片廊、计数器

一、CSS 下拉菜单&#xff1a; CSS下拉菜单用于创建一个鼠标移动上去后显示下拉菜单的效果。示例&#xff1a; <style> .dropdown { position: relative; display: inline-block; } .dropdown-content { display: none; position: absolute; background-color: #f9f…

下拉列表框Spinner

在XML文件中的创建 <Spinnerandroid:id"id/spinner"android:layout_width"wrap_content"android:layout_height"wrap_content"/> 在Java文件中的设置 //获取Spinner对象 Spinner spinnerfindViewById(R.id.spinner); //创建数组…

MoveFunsDAO 星航计划|从Move入门Web3与深入实践「公益课堂」

Move 语言作为最安全的编程语言之一&#xff0c;在资产的安全性和保护方面有着显著优势&#xff0c;被寄予引领 Web3 世界的全新叙事的厚望。 随着 Sui 在今年五月主网上线&#xff0c;它为 Move 生态带来一股新的浪潮。上线以来&#xff0c;Sui 公链的开发活跃度持续数月位居…

C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发005:守护进程与进程监控

文章目录 1 守护进程1.1 进程组和会话1.2 会话的相关概念1.3 守护进程的概念1.4 守护线程的特点1.5 守护进程创建的基本步骤1.6 本项目守护进程的实现 2 进程监控2.1 进程监控的实现 1 守护进程 1.1 进程组和会话 进程除了有进程的PID之外还有一个进程组&#xff0c;进程组是…

【Git】Git 学习笔记_操作远程仓库

1. SSH 配置和克隆仓库 ssh-keygen -t rsa -C "xxxqq.com"回车后出现以下内容&#xff0c;直接回车&#xff1a; Generating public/private rsa key pair. Enter file in which to save the key (/Users/your_user_directory/.ssh/id_rsa): (按回车键) Enter pass…

摆脱千篇一律!一文说透如何快速管理超低温冰箱

超低温冰箱在当今的科学、医疗和工业领域扮演着至关重要的角色&#xff0c;它们被广泛用于储存生物样本、疫苗、药品和实验物品等高价值、温度敏感的产品。 然而&#xff0c;为了维持这种稳定的温度环境&#xff0c;必须采取有效的监控和控制措施&#xff0c;因为即使短暂的温度…