Mr. Cappuccino的第44杯咖啡——Kubernetes之Service

news/2024/4/20 0:32:16/文章来源:https://blog.csdn.net/sinat_41888963/article/details/129216815

Kubernetes之Service

      • Service的概念
      • Service的类型
      • Service演示案例
        • 环境准备
        • ClusterIP(集群内部访问)
          • Iptables
          • IPVS
          • Endpoint
        • NodePort(对外暴露应用)
        • LoadBalancer(对外暴露应用,适用于公有云)
      • Ingress
        • 搭建Ingress环境
        • 演示案例环境准备
        • 配置http代理

Service的概念

Kubernetes Pod是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束,每个Pod都会获取它自己的IP地址,可Pod一旦销毁并重新创建后,IP地址就会发生改变。这时候我们需要通过k8s中的Service访问整个Pod集群,只要Service不被销毁,Pod就算不断发生变化,入口访问的IP总是固定的。

Service资源用于为Pod对象提供一个固定、统一的访问入口及负载均衡的能力,并借助新一代DNS系统的服务发现功能,解决客户端发现并访问容器化应用的问题。
Kubernetes中的Service是一种逻辑概念。它定义了一个Pod逻辑集合以及访问它们的策略,Service与Pod的关联同样是通过Label完成的。Service的目标是提供一种桥梁,它会为访问者提供一个固定的访问IP地址,用于在访问时重定向到相应的后端。
在这里插入图片描述

Service的类型

  1. ClusterIP:默认值,K8S系统给Service自动分配的虚拟IP,只能在集群内部访问。一个Service可能对应多个EndPoint(Pod),Client访问的是Cluster IP,通过iptables规则转到Real Server,从而达到负载均衡的效果;
  2. NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个;
  3. LoadBalancer:在NodePort的基础上,借助Cloud Provider创建一个外部的负载均衡器,并将请求转发到:NodePort,此模式只能在云服务器上使用;
  4. ExternalName:将服务通过DNS CNAME记录方式转发到指定的域名(通过spec.externlName设定);

Service演示案例

环境准备

在同一个Namespace下启动三个不同的pod

apiVersion: apps/v1
kind: Deployment
metadata:name: pc-deploymentnamespace: bubble-dev
spec:replicas: 3selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers: - name: nginximage: nginx:1.17.9ports:- containerPort: 80
kubectl delete ns bubble-dev
kubectl create ns bubble-dev
vi pc-deployment.yaml
cat pc-deployment.yaml
kubectl create -f pc-deployment.yaml

在这里插入图片描述

修改每个Pod里面的Nginx容器信息

kubectl get pod -n bubble-dev -o wide --show-labels

在这里插入图片描述
为了方便测试查看的效果,修改每个Nginx中的index.html页面为对应的IP地址

kubectl exec -it pc-deployment-97b5dbd78-66k25 -n bubble-dev /bin/sh
echo "node1节点 172.17.0.3" > /usr/share/nginx/html/index.html
exit
kubectl exec -it pc-deployment-97b5dbd78-lwws7 -n bubble-dev /bin/sh
echo "node1节点 172.17.0.2" > /usr/share/nginx/html/index.html
exit
kubectl exec -it pc-deployment-97b5dbd78-sm8q5 -n bubble-dev /bin/sh
echo "node2节点 172.17.0.4" > /usr/share/nginx/html/index.html
exit

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ClusterIP(集群内部访问)

apiVersion: v1
kind: Service
metadata:name: svc-clusteripnamespace: bubble-dev
spec:selector:app: nginx-podclusterIP: # Service的ip地址,如果不写默认会生成一个随机的IPtype: ClusterIPports:- port: 80 # Service端口targetPort: 80 # Pod端口
vi svc-clusterip.yaml
cat svc-clusterip.yaml
kubectl create -f svc-clusterip.yaml
kubectl describe svc svc-clusterip -n bubble-dev

在这里插入图片描述
在node1节点上执行

curl 10.96.26.149

在这里插入图片描述

每隔1s访问Nginx集群的IP

while true ;do curl 10.96.26.149 ; sleep 1;done;

在这里插入图片描述

分发策略:默认是随机或者轮询,自定义改成固定IP访问,即来自同一个客户端发起的所有请求都会转发到固定的一个Pod上

apiVersion: v1
kind: Service
metadata:name: svc-clusteripnamespace: bubble-dev
spec:selector:app: nginx-podclusterIP: # Service的ip地址,如果不写默认会生成一个随机的IPtype: ClusterIPports:- port: 80 # Service端口targetPort: 80 # pod端口sessionAffinity: ClientIP
kubectl delete -f svc-clusterip.yaml
rm -rf svc-clusterip.yaml
vi svc-clusterip.yaml
cat svc-clusterip.yaml
kubectl create -f svc-clusterip.yaml
kubectl describe svc svc-clusterip -n bubble-dev

在这里插入图片描述

每隔1s访问Nginx集群的IP

while true ;do curl 10.96.213.94 ; sleep 1;done;

在这里插入图片描述
在这里插入图片描述

Iptables

查看iptables的规则

iptables -t nat -nL |grep 80

在这里插入图片描述
Iptables使用NAT等技术将virtualIP的流量转至endpoint中,容器内暴露的端口是80。kube-proxy 通过iptables处理Service的过程,需要在宿主机上设置相当多的iptables规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源。

IPVS

IPVS模式的Service,可以使K8S集群支持更多量级的Pod。Pod和Service通信:通过iptables或ipvs实现通信,ipvs取代不了iptables,因为ipvs只能做负载均衡,而做不了NAT转换。

Endpoint

Endpoint是Kubernetes中的一个资源对象,存储在etcd中,用于记录一个Service对应的所有Pod的访问地址,一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。

kubectl get endpoints -n bubble-dev -o wide

在这里插入图片描述

NodePort(对外暴露应用)

在每个节点启用一个端口来暴露服务,可以在集群外部访问,通过NodeIP:NodePort访问。

在这里插入图片描述

apiVersion: v1
kind: Service
metadata:name: svc-nodeportnamespace: bubble-dev
spec:selector:app: nginx-podtype: NodePort # Service类型ports:- port: 80nodePort: 30008 # 指定绑定的node端口(默认的取值范围是: 30000-32767),如果不指定,则会默认分配targetPort: 80
kubectl delete -f svc-clusterip.yaml
vi svc-nodeport.yaml
cat svc-nodeport.yaml
kubectl create -f svc-nodeport.yaml
kubectl describe svc svc-nodeport -n bubble-dev

在这里插入图片描述

使用NodeIP:NodePort从外部访问 http://192.168.102.160:30008/

在这里插入图片描述

LoadBalancer(对外暴露应用,适用于公有云)

与NodePort类似,在每个节点启用一个端口来暴露服务。除此之外,K8S请求底层云平台的负载均衡器,把每个NodeIP:NodePort作为后端添加进去。

Ingress

由于在Pod数量多的时候,NodePort性能会急剧下降,如果K8S集群有成百上千的服务需要管理成百上千个NodePort,非常不友好。Ingress和Service、Deployment一样,Ingress也是K8S的资源类型,Ingress实现用域名的方式访问K8S集群的内部应用,Ingress受命名空间隔离。

Ingress文档

搭建Ingress环境

mkdir -p /home/ingress-controller
cd /home/ingress-controller

在这里插入图片描述

下载文件

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

如果下载不了,可以自行使用翻墙工具下载该文件或者直接使用我下面贴出来的文件

在这里插入图片描述
在这里插入图片描述

mandatory.yaml

apiVersion: v1
kind: Namespace
metadata:name: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---kind: ConfigMap
apiVersion: v1
metadata:name: nginx-configurationnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
kind: ConfigMap
apiVersion: v1
metadata:name: tcp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
kind: ConfigMap
apiVersion: v1
metadata:name: udp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
apiVersion: v1
kind: ServiceAccount
metadata:name: nginx-ingress-serviceaccountnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:name: nginx-ingress-clusterrolelabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
rules:- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ""resources:- nodesverbs:- get- apiGroups:- ""resources:- servicesverbs:- get- list- watch- apiGroups:- ""resources:- eventsverbs:- create- patch- apiGroups:- "extensions"- "networking.k8s.io"resources:- ingressesverbs:- get- list- watch- apiGroups:- "extensions"- "networking.k8s.io"resources:- ingresses/statusverbs:- update---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:name: nginx-ingress-rolenamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
rules:- apiGroups:- ""resources:- configmaps- pods- secrets- namespacesverbs:- get- apiGroups:- ""resources:- configmapsresourceNames:# Defaults to "<election-id>-<ingress-class>"# Here: "<ingress-controller-leader>-<nginx>"# This has to be adapted if you change either parameter# when launching the nginx-ingress-controller.- "ingress-controller-leader-nginx"verbs:- get- update- apiGroups:- ""resources:- configmapsverbs:- create- apiGroups:- ""resources:- endpointsverbs:- get---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:name: nginx-ingress-role-nisa-bindingnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: nginx-ingress-role
subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:name: nginx-ingress-clusterrole-nisa-bindinglabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: nginx-ingress-clusterrole
subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx---apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-ingress-controllernamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxannotations:prometheus.io/port: "10254"prometheus.io/scrape: "true"spec:# wait up to five minutes for the drain of connectionsterminationGracePeriodSeconds: 300serviceAccountName: nginx-ingress-serviceaccountnodeSelector:kubernetes.io/os: linuxcontainers:- name: nginx-ingress-controllerimage: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0args:- /nginx-ingress-controller- --configmap=$(POD_NAMESPACE)/nginx-configuration- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services- --udp-services-configmap=$(POD_NAMESPACE)/udp-services- --publish-service=$(POD_NAMESPACE)/ingress-nginx- --annotations-prefix=nginx.ingress.kubernetes.iosecurityContext:allowPrivilegeEscalation: truecapabilities:drop:- ALLadd:- NET_BIND_SERVICE# www-data -> 101runAsUser: 101env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceports:- name: httpcontainerPort: 80protocol: TCP- name: httpscontainerPort: 443protocol: TCPlivenessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 10readinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 10lifecycle:preStop:exec:command:- /wait-shutdown---apiVersion: v1
kind: LimitRange
metadata:name: ingress-nginxnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
spec:limits:- min:memory: 90Micpu: 100mtype: Container

service-nodeport.yaml

apiVersion: v1
kind: Service
metadata:name: ingress-nginxnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
spec:type: NodePortports:- name: httpport: 80targetPort: 80protocol: TCP- name: httpsport: 443targetPort: 443protocol: TCPselector:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---

执行yaml文件

kubectl apply -f ./

在这里插入图片描述

如果执行有问题,则删除命名空间

kubectl delete ns ingress-nginx

查看信息

kubectl get pod -n ingress-nginx
kubectl get svc -n ingress-nginx

在这里插入图片描述

其中30755是http协议端口,30176是为 https协议端口。

演示案例环境准备

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentnamespace: bubble-dev
spec:replicas: 3selector:matchLabels:app: nx-podtemplate:metadata:labels:app: nx-podspec:containers: - name: nginximage: nginx:1.17.9ports:- containerPort: 80---apiVersion: apps/v1 
kind: Deployment
metadata:name: tomcat-deploymentnamespace: bubble-dev
spec:replicas: 3selector:matchLabels:app: tc-podtemplate:metadata:labels:app: tc-podspec:containers:- name: tomcatimage: tomcat:9ports:- containerPort: 8080---apiVersion: v1
kind: Service
metadata:name: nginx-servicenamespace: bubble-dev
spec:selector:app: nx-podclusterIP: Nonetype: ClusterIPports:- port: 80targetPort: 80---apiVersion: v1
kind: Service
metadata:name: tomcat-servicenamespace: bubble-dev
spec:selector:app: tc-podclusterIP: Nonetype: ClusterIPports:- port: 8080targetPort: 8080
kubectl create ns bubble-dev
vi ingress.yaml
cat ingress.yaml
kubectl create -f ingress.yaml

在这里插入图片描述
在这里插入图片描述

kubectl get svc -n bubble-dev

在这里插入图片描述

配置http代理

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: ingress-httpnamespace: bubble-dev
spec:rules:- host: nginx.bubble.comhttp:paths:- path: /backend:serviceName: nginx-serviceservicePort: 80- host: tomcat.bubble.comhttp:paths:- path: /backend:serviceName: tomcat-serviceservicePort: 8080
vi ingress-http.yaml
cat ingress-http.yaml
kubectl create -f ingress-http.yaml

在这里插入图片描述

kubectl describe ing ingress-http -n bubble-dev

在这里插入图片描述

为了能看到效果,在电脑上配置host文件

C:\Windows\System32\drivers\etc

在这里插入图片描述

192.168.102.160 nginx.bubble.com
192.168.102.160 tomcat.bubble.com

在这里插入图片描述

kubectl get svc -n ingress-nginx

在这里插入图片描述
分别访问:
http://nginx.bubble.com:30755/

在这里插入图片描述

http://tomcat.bubble.com:30755/

在这里插入图片描述

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

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

相关文章

echo命令

这是一条内置命令。 输出指定的字符串 一、语法 echo [选项] [参数] 二、选项 -e&#xff1a;激活转义字符。 使用-e选项时&#xff0c;若字符串中出现以下字符&#xff0c;则特别加以处理&#xff0c;而不会将它当成一般文字输出&#xff1a; \a 发出警告声&#xff1b; \b 删…

产业链金融的前世今生

产业链金融脱胎于供应链金融&#xff0c;又不同于供应链金融。二者的区别是&#xff0c; 供应链金融服务于单个环节、单个企业&#xff0c;而产业链金融是以产业链的核心 企业为依托&#xff0c;针对产业链的各个环节&#xff0c;设计个性化、标准化的金融服务产品&#xff0c;…

阿里巴巴内网 Java 面试 2000 题解析(2023 最新版)

前言 这份面试清单是今年 1 月份之后开始收集的&#xff0c;一方面是给公司招聘用&#xff0c;另一方面是想用它来挖掘在 Java 技术栈中&#xff0c;还有一些知识点是我还在探索的&#xff0c;我想找到这些技术盲点&#xff0c;然后修复它&#xff0c;以此来提高自己的技术水平…

DNS 域名解析

介绍域名 网域名称&#xff08;英语&#xff1a;Domain Name&#xff0c;简称&#xff1a;Domain&#xff09;&#xff0c;简称域名、网域。 域名是互联网上某一台计算机或计算机组的名称。 域名可以说是一个 IP 地址的代称&#xff0c;目的是为了便于记忆。例如&#xff0c…

3.2 网站图的爬取路径

深度优先与广度优先方法都是遍历树的一种方法&#xff0c;但是网站的各个网页 之间的关系未必是树的结构&#xff0c;它们可能组成一个复杂的图形结构&#xff0c;即有回路。如果在前面的网站中每个网页都加一条Home的语句&#xff0c;让每个网页都能回到主界面&#xff0c;那么…

JasperReports studio相关操作

1.2 JasperReports JasperReports是一个强大、灵活的报表生成工具&#xff0c;能够展示丰富的页面内容&#xff0c;并将之转换成PDF&#xff0c;HTML&#xff0c;或者XML格式。该库完全由Java写成&#xff0c;可以用于在各种Java应用程序&#xff0c;包括J2EE&#xff0c;Web应…

Playbook的用法

目录 Playbook Playbook 与 Ad-Hoc 对比 YAML 语言特性 YAML语法简介 支持的数据类型 写法格式 1 scalar 标量 建议缩进两个空格&#xff0c;可多 2 Dictionary 字典 3 List 列表 三种常见的数据格式 Playbook 核心组件 不要用 tab 可以#注释 hosts remote_us…

Oracle-01-简介篇

&#x1f3c6;一、Oracle的历史和发展 Oracle公司成立于1977年&#xff0c;由拉里埃里森&#xff08;Larry Ellison&#xff09;、鲍勃明特&#xff08;Bob Miner&#xff09;和埃德奥茨&#xff08;Ed Oates&#xff09;共同创立。起初&#xff0c;公司的主要业务是开发和销售…

Lenovo Legion Y530-15ICH电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。硬件型号驱动情况主板Lenovo Legion Y530-15ICH处理器Intel Core™ i7-8750H (Coffee-Lake)已驱动内存16GB RAM DDR4 2667MHz已驱动硬盘2TB HP EX950 PCI-E Gen3 x4 NVMe SSD已驱动显卡Intel UHD Graphics 630Nvidia GTX 10…

aws console 使用fargate部署aws服务快速跳转前端搜索栏

测试过程中需要在大量资源之间跳转&#xff0c;频繁的点击不如直接搜索来的快&#xff0c;于是写了一个搜索框方便跳转。 前端的静态页面可以通过s3静态网站托管实现&#xff0c;但是由于中国区需要备案的原因&#xff0c;可以使用ecs fargate部署 步骤如下&#xff1a; 编写…

DHCP服务器的使用以及可能出现的问题(图文详细版)

DHCP服务的使用 开始&#xff0d;管理工具&#xff0d;DHCP,打开DHCP服务器选项窗口 新建作用域 在此处输入名称和描述,单击下一步 随机确定一组IP地址的范围,并指定其子网掩码 , 单击下一步 若想要排除某一个/组特定的IP地址,我们可以在此界面输入该IP地址,若没有,则可…

如何使用 FreeSql 无缝接替 EF Core ?

如何使用 FreeSql 无缝接替 EF Core&#xff0c;并实现数据表的 CRUD 操作项目说明DB & 数据表结构DB & 数据表创建数据表 User 实体模型创建使用 EF Core 实现 User 表新增用户信息添加 EF Core 相关的 nuget 包编写 EF Core 操作 User 表的 CRUD 代码FreeSql 使用 Db…

AI_Papers周刊:第三期

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 2023.02.20—2023.02.26 文摘词云 Top Papers Subjects: cs.CL 1.LLaMA: Open and Efficient Foundation Language Models 标题&#xff1a;LLaMA&#xff1a;开放高效的基础语言模型 作者&#…

zookeeper集群的搭建,菜鸟升级大神必看

一、下载安装zookeeperhttp://archive.apache.org/dist/zookeeper/下载最新版本2.8.1http://archive.apache.org/dist/zookeeper/zookeeper-3.8.1/二、上传安装包到服务器上并且解压&#xff0c;重命名tar -zxvf apache-zookeeper-3.8.1-bin.tar.gzmv apache-zookeeper-3.8.1-b…

Python安装教程(附带安装包)

首先&#xff0c;打开python安装包的下载地址&#xff0c;https://www.python.org/downloads/&#xff0c;会有些慢 点击downloads中的windows 左侧是稳定的版本&#xff0c;我这边下的是3.8的&#xff0c;不想去官网下载的可以直接用我下载的这个3.8版本&#xff0c;https://…

WebGPU学习(4)---使用 UniformBuffer

接下来让我们使用 UniformBuffer。UniformBuffer 是一个只读内存区域&#xff0c;可以在着色器上访问。 这次&#xff0c;我们将传递给着色器的矩阵存储在 UniformBuffer 中。演示示例 1.在顶点着色器中的 UniformBuffer 这次我们在顶点着色器里定义一个名为Uniforms的新结构体…

《爆肝整理》保姆级系列教程python接口自动化(二十三)--unittest断言——上(详解)

简介 在测试用例中&#xff0c;执行完测试用例后&#xff0c;最后一步是判断测试结果是 pass 还是 fail&#xff0c;自动化测试脚本里面一般把这种生成测试结果的方法称为断言&#xff08;assert&#xff09;。用 unittest 组件测试用例的时候&#xff0c;断言的方法还是很多的…

Zebec社区上线ZIP-2(地平线升级行动)提案

此前&#xff0c;Zebec社区在上线了投票治理系统Zebec Node后&#xff0c;曾上线了首个提案ZIP-1&#xff0c;对Nautilus Chain的推出进行了投票&#xff0c;作为Zebec Chain上线前的“先行链”&#xff0c;该链得到了社区用户的欢迎&#xff0c;投通过票的比例高达98.3%。而Na…

JSP网上书店系统用myeclipse定制开发mysql数据库B/S模式java编程计算机网页

一、源码特点 JSP 网上书店系统 是一套完善的系统源码&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。研究的基本内容是基于网上书店系 统&#xff0c;使用JSP作为页面开发工具。Web服务的运…

【Python工具篇】Anaconda中安装python2和python3以及在pycharm中使用

背景&#xff1a;已经安装好anaconda、python3、pycharm&#xff0c;因为项目使用的是python2语法&#xff0c;所以需要在anaconda中安装python2&#xff0c;并在pycharm中使用&#xff0c;下面给出步骤。 1. 打开cmd或者是Anaconda Prompt。 下面是anaconda prompt. 2. 查…