Kubernetes服务发布基础

        通过k8s的调度,我们可以成功的将服务部署到Kubernetes,应用部署后,最重要的就是对用户开放。

        在传统的架构中,用户访问公司内的服务可能通过了多层代理、网关、防火墙等。在Kubernetes中,访问Kubernetes中的的应用同样也会经过多层代理、网关、防火墙等。但是在传统架构中,可能是通过Nginx、Haproxy、LVS、公有云的SLB、ELB等实现的负载均衡和域名路由,虽然Kubernetes也是通过诸如此类的技术实现的域名路由或者负载均衡,只不过对应的名字叫法可能有所变化,不要把这些当做个比较新颖的东西,其实内部的实现和之前并无区别

        在传统架构配置多个相同服务的负载均衡可能使用的是Nginx的upstream 在Kubernetes中用Service实现。在传统架构配置域名访问应用可能使用Nginx的Server配置,在Kubernetes中用Ingress实现域名路由的配置

一. Service的定义

        service用于为一组提供服务的Pod抽象一个稳定的网络访问地址,是k8s实现微服务的核心概念通过Service的定义设置的访问地址是DNS域名格式的服务名称,对于客户端应用来说,网络访问方式并没有改变。Service还提供了负载均衡器的功能,将客户端请求负载分发到后端提供具体服务的各个Pod上。

        service主要用于提供网络服务,通过Service的定义,能够为客户端应用提供稳定的访问地址(域名或IP地址)和负载均衡功能,以及屏蔽后端EndPoint的变化,是Kubernetes实现微服务的核心资源        

        总之,service是kubernetes中一个非常重的概念,service用于将外部请求代理到内部pod上,提供4层负载均衡和服务发现的功能, 使得我们可以建高可用和可扩展的应用程序。

二.Service的概念和原理

        service是kubernetes中的一种抽象,用于定义一组pod以及访问这一组pod的策略、service的作用是将一组pod封装为一个虚拟的服务,并提供一个统一的入口,供客户端访问。service支持负载均衡、服务发现、服务暴露等功能。

        在kubernetes中,pod的IP地址是动态变化的,因此无法直接通过pod的IP地址进行访问servic的出现正式为了解决找个问题的。service会为一组pod创建一个虚拟的IP地址,通过这个IP地址可以访问这组pod中的任意一个pod。当客户端请求这个虚拟IP地址时,请求会被负载均衡到一组pod中的某一个pod上,从而完成对pod的访问。

    service的实现依赖于kube-proxy组件。kube-proxy会在每个节点上监听service的变化,一有service发生变化,kube-proxy会更新本地的iptables规则,从而实现流量的转发和负载均衡。另外,service还与CoreDNS有关。CoreDNS是kubernetes集群中的DNS解析服务在kubernetes中service的虚拟IP地址还会注册到CoreDNS中,从而使得客户端还可以通过service名称访问service的虚拟IP地址。在service的定义中,可以通过spec.selector字段指定哪些pod属于这个service,这样,就可以将请求负载均衡到这些pod中

        总之,service是kubernetes中一种非常重要的资源对象,它可以让pod对外提供服务,并提供负载均衡、服务发现等功能service的实现依赖于kube-proxyy和CoreDNS组件,他们共同协作,将servic与pod连接起来,实现对pod的代理访问,如下图所示。

三.Service的负载均衡机制

        当一个Service对象在Kubernetes集群中被定义出来时,集群内的客户端应用就可以通过服务IP访问到具体的Pod容器提供的服务了,从服务IP到后端Pod的负载均衡机制,则是由每个node上的kube-proxy代理来负责实现的。

kubproxy代理模式 

kube-proxy的代理模式有:userspace,iptables,ipvs和kernelspace 

1.userspace

        起初,kube-proxy进程是一个真实TCP/UDP代理,当某个pod以ClusterIP方式 访问某个service的时候,这个流量会被pod所在的本机的iptables转发到本机的kube-proxy进程,然后将请求转发到后端某个pod上。

流程:

  • kube-proxy为每个service在node上打开一个随机端口作为代理端口
  • 建立iptables规则,将Clusterip的请求重定向到代理端口
  • 到达代理端口的请求再由kuproxy转发到后端

 

2.iptables

        Kubernetes从1.2版本开始将iptables作为默认模式,这种模式下kube-proxy不再起到proxy的作用。其核心功能:通过API server的Watch接口 实时跟踪service和endpoint的变更信息,并更新对应的iptables规则,client的请求流量通过iptables的NAT机制“直接路由”到目标pod

3.ipvs模式 

  • 工作原理kube-proxy 使用 IPVS(IP Virtual Server)来处理 Service 流量。IPVS 是 Linux 内核提供的负载均衡器。
  • 优点
    • 支持更高效的负载均衡算法(如轮询、加权轮询等)。
    • 适合处理大量的并发连接和高吞吐量。
  • 缺点
    • 配置和管理可能会更复杂。
    • 需要内核支持 IPVS 模块。
  • 配置:你可以通过 kube-proxy 的配置文件来启用 IPVS 模式。
apiVersion: v1
kind: ConfigMap
metadata:name: kube-proxynamespace: kube-system
data:config.conf: |mode: "ipvs"

ipvs为负载均衡提供了更多的算法:

  • rr:轮询
  • lc:最小连接数
  • df:目标哈希
  • sh:源哈希
  • sed:预计延迟最短
  • nq:从不排队

4.kernelspace

是WIndow server上的代理模式

四.service的四种类型

1.ClusterIP

(1)介绍

        最常用的service类型, 它为pod提供了一个虚拟的IP地址。当其他Pod需要访问该Service时,它们只需要使用该虚拟IP地址即可。Kubernetes会自动将请求路由到相应的pod上。

(2)实验
1.生成用于测试Service的Deployment

        编写deployment,用于各种service的验证

        在应用service概念之前,先创建一个提供web服务的Pod集合,有两个Tomcat容器副本组成,每个容器提供的服务端口都为8080。(后续的实验都用此来测试)

(1)编写demloyment
[root@k8s-master ~]# vim webapp-deployment.yaml apiVersion: apps/v1
kind: Deployment
metadata:name: webapp
spec:replicas: 2selector:matchLabels:app: webapptemplate:metadata:labels:app: webappspec:containers:- name: webappimage: kubeguide/tomcat-app:v1ports:- name: httpcontainerPort: 8080protocol: TCP
 (2)生成pod
kubectl create -f webapp-deployment.yaml
kubectl get pod -l app=webapp -o wide
2.service的创建
2.1创建一个Cluster类型service

        描述:ClusterIP是默认service类型,它将创建一个虚拟的ClusterIp地址,用于在集群内部访问service

        使用场景:适用于集群内部的服务通信,例如将前端服务和后端服务连接起来,供内部其他服务使用。

(1)执行expose 命令暴露端口(创建service)

[root@k8s-master ~]# ku expose deployment webapp
service/webapp exposed

备注:为标签为webapp的deployment暴露一个ClusterIP类型的Kubernetes service。

(2)查看创建的service

[root@k8s-master ~]# kubectl get  svc 
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    4d6h
webapp       ClusterIP   10.108.145.159   <none>        8080/TCP   99s

(3)测试访问

[root@k8s-master ~]# curl 10.108.145.159:8080

(4)删除service

[root@k8s-master ~]# ku delete svc webapp
service "webapp" deleted
[root@k8s-master ~]# ku get  svc 
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   4d6h
2.2.使用yaml文件创建service

        除了使用expose的命令创建service外,更便于管理的方式是yaml文件来创建service

(1)编写service文件

apiVersion: v1
kind: Service
metadata:name: webapp
spec:ports:- protocol: TCPport: 8080targetPort: 8080selector:app: webapp

备注:

ports:定义的是service本身的端口号8080(用于提供给集群内部用户访问使用的端口)。

targetport:指定后端pod的容器端口号,selector定义的是后端pod所拥有的label。

(2)创建service,并测试

[root@k8s-master ~]# ku create -f webapp-service.yaml 
service/webapp created[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    4d6h
webapp       ClusterIP   10.111.18.173   <none>        8080/TCP   28s[root@k8s-master ~]# curl 10.111.18.173:8080

(3)查看endpoint列表

        一个service对应的后端由pod的IP地址和容器的端口号组成,即一个完整的IP:port访问地址,这在k8s中叫做endpoint,通过查看service 的详细信息,可以看到起后端的Endpoint列表

[root@k8s-master ~]# ku describe svc webapp
Name:              webapp
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=webapp
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.111.18.173
IPs:               10.111.18.173
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.140.71:8080,10.244.196.135:8080
Session Affinity:  None
Events:            <none>

 (4)查看endpoint资源对象

        实际上,k8s自动创建了与service关联的endpoint资源对象

[root@k8s-master ~]# ku get endpoints webapp
NAME     ENDPOINTS                                AGE
webapp   10.244.140.71:8080,10.244.196.135:8080   7m52s

(5)删除这个service

kubectl delete -f webapp-service.yaml 
service "webapp" deleted
[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   4d6h

或者

[root@k8s-master ~] ku delete svc webapp
service "webapp" deleted
[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   4d6h

 2.NodePort

(1)解释

        这种Service类型将pod公开为集群中所有节点上的某个端口,当外部请求到达任何一个节点上的该端口时,Kubernetes会将请求路由到响应的Pod上。

 (2)实验
1.基础环境deployment
2.创建nodeport类型的service

        描述:NodePort将在每个节点上公开一个端口,并将流量转发到service。他会创建一个clusterIP,并使用端口映射到每个节点的相同端口。

        使用场景:适用与需要从外部访问集群中的服务时,可以通过节点的IP地址和映射的端口进行访问。这对于开发和测试环境非常重要。

(1)创建service文件

设置service类型为NodePort,并设置具体的nodePort端口号为30008

[root@k8s-master ~]# vim webapp-svc-nodeport.yaml apiVersion: v1
kind: Service
metadata:name: webapp
spec:type: NodePortports:- port: 8080targetPort: 8080nodePort: 30008selector:app: webapp

备注:port :设置的是 Service 对象暴露的端口,用于集群内部通信

           targetport: 容器内部的端口号。Service 将请求转发到这个端口。这个端口通常是 Pod 内运行的应用服务的端口。

           nodePort:Service 类型为 NodePort 时,nodePort 是 Kubernetes 集群的每个节点上暴露的端口号,允许外部流量通过此端口访问 Service

(2)创建和查看与ClusterIP类型相同
[root@k8s-master ~]# ku create -f webapp-svc-nodeport.yaml 
service/webapp created
[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          4d7h
webapp       NodePort    10.109.129.168   <none>        8080:30008/TCP   6s
(3)测试在WIndow宿主机上用浏览器测试访问

Apache Tomcat/8.0.35icon-default.png?t=N7T8http://192.168.10.101:30008/ 

3.LoadBalancer类型

(1)介绍

         LoadBalancer  Service:这种Service类型使用云提供商的负载均衡器将请求路由到后端Pod。Kubernetes会自动创建和配置负载均衡器,并将其绑定到service上。

 (2)实验

        通常在公有云的环境中会使用LoadBalancer的类型,可以将Service映射到公有云提供的某个负载均衡器的IP地址上,客户端通过负载均衡器的IP和Service的端口号就可以访问到具体的服务。

        描述:LoadBalancer为Service创建一个外部负载均衡器,并分配一个外部IP地址。它通常由云提供商的负载均衡服务实现

        使用场景:适用于需要将流量从外部负载均衡器分发到集群内部的服务,例如在生产环境中暴露web应用程序。

1.编写LoadBalancer
[root@k8s-master ~]# vim webapp-svc-loadbalancer.yaml apiVersion: v1
kind: Service
metadata:name: webappnamespace: defaultlabels:app: webapp
spec:type: LoadBalancerports:- port: 8080targetPort: httpprotocol: TCPname: httpselector:app: webapp

备注:这个service创建好后,云服务商会在service定义中补充LoadBalancer的IP地址,之后可以在客户端访问该Service

nodePort的端口范围在30000-32767之间 

2.创建并查看
[root@k8s-master ~]# ku create -f webapp-svc-loadbalancer.yaml 
service/webapp created
[root@k8s-master ~]# ku get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP          4d7h
webapp       LoadBalancer   10.109.149.6   <pending>     8080:30287/TCP   6s

因为没有连到云服务商后面的操作不在演示。 

4. ExternalName

(1)介绍

        externalName Service:这种service类型允许你将service映射到集群外部的某个名称。当Pod需要访问该service时,它们将使用该名称来解析出相应的IP地址

(2)实验 

        描述:ExternalName允许Service通过返回CNAME记录来引用集群外部的服务。它没有clusterIP,NodePort或 LoadBalancer

        使用场景:适用于需要将K8s内部的服务与集群外的现有服务进行关联,例如连接到外部的数据库或其他资源。        

        ExternalName类型是Service的特例,用于将集群外的服务定义为Kubernetes的集群Service并通过ExternalName字段指定外部服务的地址,可以使用域名或IP格式。集群内客户端应用通过访问这个Service就能访问外部服务了。他没有选择器,没有定义任何端口和Endpoint,他通过返回该外部服务的别名来提供服务。也可以用于两个不同的namespace之间的不同pod可以通过name的形式访问。

注意:

        两个不同的命名空间中的pod,可以直接使用他们的IP地址进行通信,但是pod的IP地址是随机分配的,重建pod后其IP地址就改变了,因此我们要用pod对应的service名称进行通信。但是跨命名空间是不能解析其他命名空间中创建的service名称的。这个时候就可以使用ExternalName实现两个不同命名空间中的各个pod间的通信

1.创建两个命名空间
[root@k8s-master ~]# ku create namespace test01
[root@k8s-master ~]# ku create namespace test02
2.第一个pod
(1)编写命名空间为test01的Pod文件并创建pod
[root@k8s-master ~]# vim myapp01.yaml apiVersion: apps/v1
kind: Deployment
metadata:name: myapp01namespace: test01
spec:replicas: 1selector: #标签选择器matchLabels: #匹配的标签为app: myapp01release: canarytemplate:metadata:labels:app: myapp01 #和上面的myapp要匹配release: canaryspec:containers:- name: myappimage: ikubernetes/myapp:v1ports:- name: http01containerPort: 80

 创建该pod

ku create -f myapp01.yaml
(2)创建一个无头(headless)service
[root@k8s-master ~]# vim myapp-svc-headless01.yaml apiVersion: v1
kind: Service
metadata:name: myapp-svc01namespace: test01
spec:selector:app: myapp01 #挑选的pod还是myapp01。一个pod可以有多个servicerelease: canaryclusterIP: None #None表示是无头serviceports:- port: 39320 #service ip中的端口targetPort: 80 #容器ip中的端口

备注:

 (HeadlessService)无头Service:这种服务没有入口地址(没有clusterIP),kube-proxy也不会为其创建负载转发的规则,服务名的解析机制取决于这个无头Service是否设置了标签选择器

注意:

无头服务创建出来之后,对于其他外部的pod来讲,该pod对应的名字就确定了下来,其固定的格式是:无头服务名.命名空间.svc.cluster.local

[root@k8s-master ~]# ku create -f myapp-svc-headless01.yaml 
(3)创建extername
[root@k8s-master ~]# vim myapp-svc-extername01.yaml kind: Service
apiVersion: v1
metadata:name: myapp-svcname02namespace: test01
spec:type: ExternalNameexternalName: myapp-svc02.test02.svc.cluster.local

备注:

name:myapp-是vcname02 指的是外部的服务名称

myapp-svc02.test02.svc.cluster.local    对方无头服务的名称.对方命令空间的名称.svc.cluster.local

可用以下命令查看

[root@k8s-master ~]# ku get svc -n test01
NAME              TYPE           CLUSTER-IP   EXTERNAL-IP                            PORT(S)     AGE
myapp-svc01       ClusterIP      None         <none>                                 39320/TCP   8h
myapp-svcname02   ExternalName   <none>       myapp-svc02.test02.svc.cluster.local   <none>      8h

 备注:myapp-svc02.test02.svc.cluster.local为对方nds的名称,是能通过名称访问的

 创建

[root@k8s-master ~]# ku create -f myapp-svc-extername01.yaml 
3.第二个pod
(1)编写并创建命名空间为test02的pod
[root@k8s-master ~]# vim myapp02.yaml apiVersion: apps/v1
kind: Deployment
metadata:name: myapp02namespace: test02
spec:replicas: 1selector: #标签选择器matchLabels: #匹配的标签为app: myapp02release: canarytemplate:metadata:labels:app: myapp02 #和上面的myapp要匹配release: canaryspec:containers:- name: myapp02image: ikubernetes/myapp:v1ports:- name: http02containerPort: 80

创建pod

ku create -f myapp02.yaml 
(2)创建无头(headless)service
[root@k8s-master ~]# vim myapp-svc-headless02.yaml apiVersion: v1
kind: Service
metadata:name: myapp-svc02namespace: test02
spec:selector:app: myapp02 #挑选的pod还是myapp。一个pod可以有多个servicerelease: canaryclusterIP: None #None表示是无头serviceports:- port: 39320 #service ip中的端口targetPort: 80 #容器ip中的端口

创建无头service

ku create -f myapp-svc-headless02.yaml 
(3)创键extername
[root@k8s-master ~]# vim myapp-svc-extername02.yaml kind: Service
apiVersion: v1
metadata:name: myapp-svcname01namespace: test02
spec:type: ExternalNameexternalName: myapp-svc01.test01.svc.cluster.local

创建

ku create -f myapp-svc-extername02.yaml
4.验证pod间的通信
[root@k8s-master ~]# ku get pods -n test01NAME                       READY   STATUS    RESTARTS   AGE
myapp01-696c886d6b-2p5ks   1/1     Running   0          8h
[root@k8s-master ~]# ku exec -it myapp01-696c886d6b-2p5ks -n test01 -- sh/ # ping myapp-svcname02
PING myapp-svcname02 (10.244.140.72): 56 data bytes
64 bytes from 10.244.140.72: seq=0 ttl=62 time=1.131 ms
64 bytes from 10.244.140.72: seq=1 ttl=62 time=0.300 ms
[root@k8s-master ~]# ku get pod -n test02 -o wideNAME                       READY   STATUS    RESTARTS   AGE   IP              NODE     NOMINATED NODE   READINESS GATES
myapp02-55ffcd5f64-w9tw4   1/1     Running   0          8h    10.244.140.72   node02   <none>           <none>
[root@k8s-master ~]# ku get pod -n test01 -o wideNAME                       READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
myapp01-696c886d6b-2p5ks   1/1     Running   0          8h    10.244.196.136   node01   <none>           <none>

五。service的其他应用

service的多端口设置

        一个容器应用可以提供多个端口的服务,在service的定义中可以相应的设置多个端口号

(1)创建文件

[root@k8s-master ~]# vim service-multiple-ports.yaml apiVersion: v1
kind: Service
metadata:name: webapp
spec:ports:- port: 8080targetPort: 8080name: webprotocol: TCP- port: 8005targetPort: 8005name: managementprotocol: TCPselector:app: webapp

注意:selector中的app:webapp的标签对应的是webapp-deployment.yaml的pod标签

(2)创建service

[root@k8s-master ~]# ku create -f service-multiple-ports.yaml 
service/webapp created

(3)查看endpoint列表

[root@k8s-master ~]# ku describe svc webapp
Name:              webapp
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=webapp
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.107.175.37
IPs:               10.107.175.37
Port:              web  8080/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.140.71:8080,10.244.196.135:8080
Port:              management  8005/TCP
TargetPort:        8005/TCP
Endpoints:         10.244.140.71:8005,10.244.196.135:8005
Session Affinity:  None
Events:            <none>

(4)查看创建的service

[root@k8s-master ~]# ku get svc webapp
NAME     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
webapp   ClusterIP   10.107.175.37   <none>        8080/TCP,8005/TCP   96s

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

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

相关文章

Windows下使用QT5.14.2编译MySQL8.0对应的最新64位驱动程序步骤

不得不说mysql更新的速度是真的快&#xff0c;最近一两年都更新了好几个的小版本了。如果安装了高版本的 mysql软件&#xff0c;低版本的驱动就不支持了&#xff0c;因此需要重新使用QT来编译对应的mysql驱动。具体办法如下&#xff1a; 1、官网下载最新的mysql8.0安装包。下载…

ABAP 引用变量(TYPE REF TO )和字段符号(FIELD-SYMBOLS)全集

本文主要是记录了一些关于ABAP 引用变量(TYPE REF TO )和字段符号(FIELD-SYMBOLS)的相关内容&#xff0c;有些参考来自多个博客&#xff0c;以及官方文档 文章目录 FIELD-SYMBOLS字段符号官方文档Declaring Field SymbolsTyping Field Symbols 引用变量文章1引用变量介绍测试程…

Linux文件属性和打包压缩详解

1、文件属性体系 1.1 文件系统概述 [rootyunwei /]# ls -lhi 总用量 72K3505 lrwxrwxrwx. 1 root root 7 3月 7 2019 bin -> usr/bin 262152 dr-xr-xr-x. 5 root root 4.0K 12月 19 16:00 boot 399635 drwxr-xr-x 2 root root 4.0K 11月 5 2019 data1026 drw…

electron-vite封装UI级的消息提示

说明 Electron Vite Vue3 Element Plus Electron中写提示有两种方案&#xff1a; 系统级&#xff1a;electron带的dialog相关APIUI级&#xff1a;UI框架内部的提示&#xff0c;如ElMessage、ElMessageBox、ElNotification等 今天来封装一下UI级别的提示 代码 效果图 源…

冷却液温度传感器检测诊断

检测发动机冷却液温度&#xff0c;向ECU输入温度信号&#xff0c;作为燃油喷射和点火正时的修正信号&#xff0c;同时也是其他控制系统的控制信号。 冷却液温度传感器安装位置 冷却液温度传感器&#xff08;俗称水温传感器&#xff09;一般安装在缸体水道上&#xff0c;缸盖水…

知识竞赛答题设备及答题方式有哪些

根据我们多年的知识竞赛承办经验&#xff0c;我来谈谈在知识竞赛中常用的答题设备和答题方式。 一、常用答题设备 1.电脑 如果电脑资源充足&#xff0c;可以用笔记本电脑进行答题&#xff0c;笔记本电脑可以采取有线或无线方式进行连网&#xff0c;可以根据情况选择连网方案&…

利用GPT绘制流程图(无需下载任何软件

目录 什么是Flowchart Fun&#xff1f;如何利用GPT绘制流程图&#xff1f;步骤1&#xff1a;确定流程图的目的和内容步骤2&#xff1a;训练GPT编写流程图的文本描述步骤3&#xff1a;转换文本格式为可视化的流程图步骤4&#xff1a;调整和优化 结论小结&#xff1a; 什么是Flow…

Tomcat部署项目get请求中文乱码

问题描述 tomcat部署的项目&#xff0c;get请求到后端后&#xff0c;打印日志发现通过RequestParam()接收的参数值乱码。 问题猜测 编码错误导致的乱码。 流程梳理 浏览器发送请求时会自动对请求链接中自带的参数进行编码。编码时一般都是采用UTF-8的格式进行编码。请求到…

Ubuntu 22.04 某次重启后nvidia-smi 失效

Ubuntu 22.04 某次重启后nvidia-smi 失效 某次重启后失效&#xff0c;遂在网上寻找答案&#xff1a; 方案一&#xff1a;使用dkms进行安装相应模块 具体的可以参考链接 dkms 但是我试了一下并不好用&#xff0c;并且报错如下&#xff1a; Building module:cleaning build a…

token令牌,过滤器,JWT,拦截器

令牌(token)技术 不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了 1.基本流程 用户使用用户名密码来请求服务器 服务器进行验证用户的信息 服务器通过验证发送给用户一个token 客户端存储token&#…

探索大语言模型在DNA 分析到表达预测以及生物信息学应用

概述 论文地址&#xff1a;https://arxiv.org/abs/2401.04155 随着 OpenAI 的 GPT-X 和谷歌的 BERT 等大规模语言模型的出现&#xff0c;自然语言处理领域得到了飞速发展。这些先进的模型将理解和生成人类语言的能力发挥到了极致&#xff0c;彻底改变了日常交流和业务流程。 …

Axure设计之动态条形图教程(中继器)

在Axure RP中&#xff0c;中继器是一个非常强大的工具&#xff0c;它允许我们动态地展示数据&#xff0c;并且可以轻松实现复杂的交互效果。本文将详细介绍如何使用中继器来制作一个动态条形图&#xff0c;并展示其在实际项目中的应用。 一、效果预览 预览地址&#xff1a;http…

存储与传输/大小端字节序的概念、决定因素、给编程带来的困扰

文章目录 概述大小端分歧的类比为什么要关注字节序NET网络字节序什么时候必须转换字节序大小端字节序哪个优秀判断系统字节序类型字节序类型转换大小端内存监视和调试 谁决定了大小端模式CPU架构决定大小端操作系统影响大小端&#xff1f;编译器也影响大小端&#xff1f;可配置…

如何完美备份自己的微博,即使是封号之后

感谢 https://github.com/Chilfish/Weibo-archiver 工具和环境 可以用chrome插件的浏览器&#xff0c; 比如opera安装篡改猴插件安装nodejsvscode 第一步&#xff0c;安装浏览器插件 安装Tampermonkey 然后打开https://raw.githubusercontent.com/Chilfish/Weibo-archiver/m…

MS2232/MS2232T——±20kV ESD 保护、3V-5.5V 供电、真 RS-232 收发器

MS2232/MS2232T 芯片是集成电荷泵、具有 20kV ESD 保护的 RS-232 收发器&#xff0c;包括两路接收器、两路发送器。芯 片满足 TIA/EIA-232 标准&#xff0c;为异步通信控制器和串口连接器 提供通信接口。 芯片采用 3V-5.5V 供电&#xff0c;电荷泵仅用 4 个 0.1-0.47μF 小…

c++ 谷歌的招聘 题解

题目描述 2004 年 7 月,谷歌在硅谷的 101 号公路边竖立了一块巨大的广告牌(如下图)用于招聘 内容超级简单,就是一个以 .com 结尾的网址,而前面的网址是一个 10 位素数,这个素数是自然常数 e 中最早出现的 10 位连续数字 能找出这个素数的人,就可以通过访问谷歌的这个网站进入…

Final Cut Pro Mac(fcpx专业视频剪辑软件) 10.8 中文版安装

Final Cut Pro 是苹果公司为专业视频编辑人士量身打造的非线性编辑软件&#xff0c;以其卓越的性能和深度定制的工具集&#xff0c;在影视制作、电视广播、广告创意等多个领域占据了重要地位。凭借其对高分辨率视频的无缝支持和实时剪辑的流畅体验&#xff0c;Final Cut Pro 成…

【Linux】简易日志工具项目

有些鸟儿是不应该被关在笼子里的&#xff0c; 因为他们的羽毛太丰润了。 当他们飞走&#xff0c;你会由衷地庆贺他获得自由。 --- 肖申克的救赎》--- 从零开始构建简易日志系统 1 日志1.1 什么是日志1.2 日志的意义1.3 为什么要构建自己的日志工具 2 构建自己的日志工具2.1…

gin快速入门

gin 项目地址晓智科技晓智科技晓智文档晓智文档文档源码文档源码 快速体验 func HandlerPong(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",}) }func main() {r : gin.Default()r.GET("/ping", HandlerPong)_ r.Run(&qu…

Windows电脑自建我的世界MC服务器并与好友远程联机游戏教程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…