云原生后端:解锁高效可扩展应用的魔法世界
目录
一、云原生后端的崛起:时代的必然选择
二、云原生后端的基石:容器化与 Docker
(一)容器化的概念与优势
(二)Docker:容器化的明星工具
三、微服务架构:云原生后端的灵魂
(一)微服务架构的原理与特点
(二)微服务的通信与交互
四、Kubernetes:云原生后端的超级管家
(一)Kubernetes 的核心功能与架构
(二)Kubernetes 的资源对象与部署实践
五、云原生后端的监控与可观测性
(一)监控的重要性与目标
(二)常用的监控工具与技术
一、云原生后端的崛起:时代的必然选择
在当今数字化飞速发展的时代,企业对软件应用的要求达到了前所未有的高度。传统的后端架构在面对高并发、快速迭代、复杂部署环境等挑战时,逐渐显得力不从心。云原生后端应运而生,它就像是为应对现代应用困境量身定制的一把利剑。
云原生后端是一种基于云计算技术构建和运行应用程序后端的方法。它充分利用了云计算的弹性、可扩展性和资源池化等特性。其核心目标是让开发人员能够更高效地构建、部署和管理后端服务,同时保证应用在面对各种复杂场景时的高可用性和高性能。
从宏观角度来看,云原生后端的出现是技术发展和市场需求共同作用的结果。随着互联网用户数量的爆炸式增长以及业务场景的日益多样化,企业需要能够快速响应市场变化的软件架构。传统后端架构的冗长开发周期、复杂的部署流程以及有限的扩展性,已经成为企业发展的瓶颈。云原生后端打破了这些限制,开启了一个全新的开发和部署模式。
二、云原生后端的基石:容器化与 Docker
(一)容器化的概念与优势
容器化是云原生后端的重要基础。它将应用程序及其所有依赖项(包括代码、运行时环境、系统工具、系统库等)打包成一个标准的、独立的单元,这个单元就是容器。容器在运行时与宿主机以及其他容器相互隔离,就像一个个独立的小盒子。
容器化的优势是多方面的。首先,它实现了环境的一致性。无论是在开发人员的本地机器、测试环境还是生产环境,只要使用相同的容器镜像,应用就能以相同的方式运行。这极大地减少了因环境差异导致的问题,如 “在我这里运行没问题啊” 这种经典的开发与运维矛盾。
其次,容器具有轻量级的特点。与传统的虚拟机相比,容器不需要运行一个完整的操作系统内核,而是共享宿主机的内核,这使得容器的启动速度更快、资源占用更少。例如,一个简单的基于 Linux 的容器启动可能只需要几秒钟,而启动一个完整的虚拟机可能需要几分钟。
再者,容器化方便了应用的迁移和部署。由于容器包含了应用运行所需的一切,将其从一个环境迁移到另一个环境就变得非常简单。只要目标环境支持容器运行时(如 Docker 引擎),就可以轻松部署应用。
(二)Docker:容器化的明星工具
Docker 是目前最流行的容器化平台。它为容器的创建、管理和分发提供了一套完整的工具和工作流程。
下面通过一个简单的例子来了解 Docker 的使用。假设我们有一个简单的 Python Web 应用,其代码如下:
from flask import Flaskapp = Flask(__name__)@app.route('/') def hello_world():return 'Hello, World!'if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)
要将这个应用容器化,我们首先需要创建一个 Dockerfile。Dockerfile 是一个文本文件,其中包含了构建 Docker 镜像的指令。
# 使用官方的 Python 3.9 基础镜像 FROM python:3.9# 设置工作目录 WORKDIR /app# 将当前目录下的所有文件复制到容器的 /app 目录下 COPY. /app# 安装应用所需的依赖项(这里假设使用 requirements.txt 文件来管理依赖) RUN pip install -r requirements.txt# 暴露应用运行的端口 EXPOSE 5000# 定义容器启动时要运行的命令 CMD ["python", "app.py"]
有了 Dockerfile 后,我们可以在包含应用代码和 Dockerfile 的目录下执行以下命令来构建 Docker 镜像:
docker build -t my-python-app.
这里的 “-t” 参数用于指定镜像的标签(tag),“my - python - app” 是我们给镜像起的名字,最后的 “.” 表示当前目录,即 Docker 会在当前目录下寻找 Dockerfile。
构建好镜像后,我们可以使用以下命令来运行容器:
docker run -p 5000:5000 my-python-app
这里的 “-p” 参数用于将宿主机的端口映射到容器内的端口,这样我们就可以通过宿主机的 IP 和映射的端口访问容器内运行的应用了。通过这个简单的例子,我们可以看到 Docker 是如何方便地将一个应用容器化并运行的。
三、微服务架构:云原生后端的灵魂
(一)微服务架构的原理与特点
微服务架构是云原生后端的核心设计模式。它将一个大型的、复杂的应用程序拆分成多个小型的、独立的服务,每个服务都专注于完成一个特定的业务功能。这些微服务可以独立开发、独立部署、独立扩展,并且通过轻量级的通信机制相互协作。
微服务架构的特点使其具有诸多优势。首先,它提高了开发效率。不同的微服务可以由不同的团队负责开发,团队可以根据自身的专长和业务需求选择合适的技术栈。例如,用户认证服务可以使用 Java 和 Spring Security,而订单处理服务可以使用 Python 和 Django,这样可以充分发挥不同技术的优势。
其次,微服务架构增强了系统的可扩展性。当某个微服务的负载增加时,可以独立地对该微服务进行扩展,而不需要对整个应用进行扩展。比如,电商系统中的订单服务在购物高峰期负载增大,可以单独增加订单服务的实例数量,而不会影响其他如商品浏览等服务。
再者,微服务架构提高了系统的可靠性。由于每个微服务都是独立的,如果某个微服务出现故障,不会导致整个系统崩溃。其他微服务可以继续正常运行,并且可以通过一些容错机制(如断路器模式)来应对故障微服务的影响。
(二)微服务的通信与交互
微服务之间需要进行通信和交互来完成业务流程。常见的通信方式有 RESTful API 和消息队列。
- RESTful API
RESTful API 是一种基于 HTTP 协议的轻量级通信方式。每个微服务可以通过暴露一组 RESTful 端点来与其他微服务交互。例如,一个用户服务可能有以下的 RESTful API 端点:
GET /users/{id}
:用于获取指定 ID 的用户信息。POST /users
:用于创建新用户。以下是一个使用 Python 的 Flask 框架实现的简单的用户服务 RESTful API 示例:
from flask import Flask, jsonify, request import users_database # 假设这是一个处理用户数据的模块app = Flask(__name__)# 获取用户信息的端点 @app.route('/users/<int:id>', methods=['GET']) def get_user(id):user = users_database.get_user(id)return jsonify(user)# 创建用户的端点 @app.route('/users', methods=['POST']) def create_user():data = request.get_json()new_user = users_database.create_user(data)return jsonify(new_user), 201
- 消息队列
消息队列用于在微服务之间实现异步通信。当一个微服务产生一个事件时,它可以将消息发送到消息队列中,其他对该事件感兴趣的微服务可以从消息队列中获取消息并进行处理。常见的消息队列系统有 RabbitMQ 和 Kafka。例如,在一个电商系统中,当用户下单后,订单服务可以将订单信息发送到消息队列中。库存管理服务和物流服务可以从消息队列中获取订单信息,分别进行库存扣减和物流安排等操作。以下是一个使用 Python 和 RabbitMQ 实现的简单消息发送和接收的示例:
发送消息(订单服务):
import pika# 建立与 RabbitMQ 的连接 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel()# 声明一个队列 channel.queue_declare(queue='order_queue')# 订单信息 order_info = {'order_id': 123,'product_id': 456,'quantity': 1 }# 将订单信息发送到消息队列 channel.basic_publish(exchange='', routing_key='order_queue', body=json.dumps(order_info))# 关闭连接 connection.close()
接收消息(库存管理服务):
import pika import jsondef callback(ch, method, properties, body):order_info = json.loads(body)# 在这里进行库存扣减操作print(f"Received order: {order_info}")# 建立与 RabbitMQ 的连接 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel()# 声明一个队列 channel.queue_declare(queue='order_queue')# 注册回调函数来接收消息 channel.basic_consume(queue='order_queue', on_message_callback=callback, auto_ack=True)# 开始接收消息 channel.start_consuming()
四、Kubernetes:云原生后端的超级管家
(一)Kubernetes 的核心功能与架构
Kubernetes 是一个开源的容器编排平台,它在云原生后端中扮演着至关重要的角色。它可以自动化地管理容器的部署、扩展、调度和维护等操作。
Kubernetes 的核心架构主要包括以下几个组件:
Master 节点:
- API Server:这是 Kubernetes 的前端接口,所有的资源操作(如创建、更新、删除 Pod、Service 等)都通过 API Server 进行。它对外提供了 RESTful API,供用户和其他系统组件与 Kubernetes 集群交互。
- Scheduler:负责将 Pod 调度到合适的 Node 节点上运行。它会根据 Node 的资源状况(如 CPU、内存等)、Pod 的资源需求以及一些调度策略(如亲和性、反亲和性等)来做出调度决策。
- Controller Manager:包含了多个控制器,如 ReplicaSet 控制器、Deployment 控制器等。这些控制器负责监控集群的状态,并根据预设的规则对资源进行调整。例如,ReplicaSet 控制器会确保指定数量的 Pod 副本在集群中运行。
Node 节点:
- Kubelet:运行在每个 Node 节点上,它负责与 Master 节点通信,接收并执行 Master 节点下发的指令,如启动、停止 Pod 等。同时,它还会监控容器的运行状态,并向 Master 节点反馈。
- Kube - Proxy:负责实现 Kubernetes 集群内的服务发现和负载均衡。它通过在 Node 节点上维护网络规则,将对服务的请求转发到对应的 Pod 上。
(二)Kubernetes 的资源对象与部署实践
- Pod
Pod 是 Kubernetes 中最小的可部署和可管理的计算单元。一个 Pod 可以包含一个或多个紧密相关的容器,这些容器共享网络和存储资源。例如,一个简单的包含一个容器的 Pod 配置文件(YAML 格式)如下:apiVersion: v1 kind: Pod metadata:name: my - simple - pod spec:containers:- name: my - containerimage: nginx:latest
这个配置文件定义了一个名为 “my - simple - pod” 的 Pod,其中包含一个名为 “my - container” 的容器,使用的是 “nginx:latest” 镜像。
- Deployment
Deployment 是用于管理 Pod 的创建、更新和扩展的资源对象。它提供了一种声明式的方式来部署应用。以下是一个简单的 Deployment 配置文件:apiVersion: apps/v1 kind: Deployment metadata:name: my - app - deployment spec:replicas: 3selector:matchLabels:app: my - apptemplate:metadata:labels:app: my - appspec:containers:- name: my - app - containerimage: my - app - image:latest
在这个配置文件中,“replicas” 字段指定了要创建的 Pod 副本数量为 3。“selector” 用于选择要管理的 Pod,这里通过 “app: my - app” 标签来选择。“template” 部分定义了 Pod 的模板,包括 Pod 的标签和容器信息。通过这个 Deployment,Kubernetes 会自动创建并维护 3 个运行 “my - app - image:latest” 镜像的 Pod。
- Service
Service 用于在 Kubernetes 集群内实现服务发现和负载均衡。它为一组具有相同功能的 Pod 提供了一个统一的访问入口。以下是一个简单的 ClusterIP 类型的 Service 配置文件:apiVersion: v1 kind: Service metadata:name: my - service spec:type: ClusterIPselector:app: my - appports:- protocol: TCPport: 80targetPort: 8080
这个 Service 会将对集群内 “my - service” 的 80 端口的请求,负载均衡到具有 “app: my - app” 标签的 Pod 的 8080 端口上。这使得其他微服务可以通过 “my - service” 这个统一的名称来访问相关的 Pod,而不需要知道具体的 Pod IP 地址。
五、云原生后端的监控与可观测性
(一)监控的重要性与目标
在云原生后端环境中,监控是保障系统稳定运行的关键环节。随着系统的复杂性增加,特别是在微服务架构和容器化环境下,需要实时了解系统的运行状态,包括各个微服务的性能、容器的资源使用情况、网络状况等。
监控的主要目标包括:
- 性能优化:通过监控资源使用情况(如 CPU、内存、网络带宽等),可以发现性能瓶颈,及时调整资源分配或优化代码,以提高系统的整体性能。例如,如果发现某个微服务的 CPU 使用率长期过高,可以分析是业务逻辑问题还是资源不足,进而采取相应的措施,如优化算法或增加资源。
- 故障预警与快速定位:实时监测系统状态可以在故障发生前发现异常迹象,如某个微服务的响应时间突然变长、错误率增加等。在故障发生后,监控数据可以帮助快速定位问题所在,是某个容器出现问题、网络故障还是微服务内部的逻辑错误。
- 资源管理与成本控制:了解资源的使用情况有助于合理分配资源,避免资源浪费。在云环境中,资源的使用是计费的,通过监控可以确保企业在满足业务需求的同时,控制成本。例如,如果发现某个环境中存在大量闲置的容器资源,可以及时调整资源配置。
(二)常用的监控工具与技术
- Prometheus
Prometheus 是一款开源的监控和告警系统,广泛应用于云原生后端环境。它具有以下特点:
- 多维数据模型:Prometheus 以时间序列数据的形式存储监控数据,每个数据点都有一个时间戳和一组标签。这种多维数据模型可以方便地对数据进行查询和分析。例如,可以通过查询具有特定标签(如微服务名称、环境等)的数据来获取某个微服务在不同时间的性能指标。
- 强大的查询语言:Prometheus 提供了 PromQL(Prometheus Query Language),可以用于编写复杂的查询语句。例如,可以使用 PromQL 查询某个微服务在过去 5 分钟内的平均 CPU 使用率:
rate(process_cpu_usage{service="my - service"}[5m])
。- 多种数据采集方式:Prometheus 可以通过多种方式采集数据,包括直接从应用程序中暴露的指标端点(通常是 HTTP 端点)采集,或者使用各种 Exporter 来采集不同系统(如数据库、消息队列等)的指标。以下是一个简单的 Python 应用程序暴露 Prometheus 指标的示例:
from prometheus_client import start_http_server, Gauge import random import time# 创建一个 Gauge 类型的指标,用于表示某个值 my_gauge = Gauge('my_metric', 'This is my metric')if __name__ == '__main__':# 启动一个 HTTP 服务器,用于暴露指标,端口为 8000start_http_server(8000)while True:# 设置指标的值为一个随机数my_gauge.set(random.randint(0, 100))time.sleep(5)
- Grafana
Grafana 是一个开源的可视化和分析平台,常与 Prometheus 配合使用。它可以从 Prometheus 等数据源获取数据,并创建各种美观、直观的仪表盘。通过 Grafana,可以轻松地将监控数据以图表、表格等形式展示出来,方便运维人员和开发人员分析。例如,可以创建一个仪表盘来展示多个微服务的 CPU 使用率、内存使用率、请求响应时间等指标随时间的变化情况。
相关文章:

云原生后端:解锁高效可扩展应用的魔法世界
目录 一、云原生后端的崛起:时代的必然选择 二、云原生后端的基石:容器化与 Docker (一)容器化的概念与优势 (二)Docker:容器化的明星工具 三、微服务架构:云原生后端的灵魂 &…...

大数据新视界 -- Hive 数据湖架构中的角色与应用(上)(25 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

React高阶面试题目(六)
React的formik库 定义: Formik是一个用于在React应用程序中构建和处理表单数据的流行开源库。它提供了许多实用的组件和函数,使在React应用程序中处理表单数据变得更加轻松。 优点: 自动处理表单状态管理,无需手动编写大量的状态…...

容器运行应用及Docker命令
文章目录 一、使用容器运行Nginx应用1_使用docker run命令运行Nginx应用1 观察下载容器镜像过程2 观察容器运行情况 2_访问容器中运行的Nginx服务1 确认容器IP地址2 容器网络说明3 使用curl命令访问 二、Docker命令1_Docker命令获取帮助方法2_Docker官网提供的命令说明3_docker…...

【Go 基础】channel
Go 基础 channel 什么是channel,为什么它可以做到线程安全 Go 的设计思想就是:不要通过共享内存来通信,而是通过通信来共享内存。 前者就是传统的加锁,后者就是 channel。也即,channel 的主要目的就是在多任务间传递…...

windows10更新后system磁盘占用100%
windows10更新后system磁盘占用100% 现象: 解决办法: 打开服务禁用:Connected User Experiences and Telemetry 我现在已经把该服务禁用了,已经没有再出现不停写入的情况。 服务描述:“已连接的用户体验和遥测服务所…...

无人设备遥控器之防水性能篇
无人设备遥控器的防水性能是评估其耐用性和适应不同环境能力的重要指标。随着无人设备技术的不断发展,越来越多的遥控器在设计时融入了防水元素,以满足用户在不同天气条件下的使用需求。 一、防水等级与标准 无人设备遥控器的防水性能通常通过防水等级来…...

基于Matlab BP神经网络的非线性系统辨识与控制研究
随着现代工业和科学技术的不断发展,非线性系统的建模和控制成为了自动化领域中的重要研究课题。传统的系统辨识方法往往难以应对系统的复杂性和非线性特性,而人工神经网络(ANN)凭借其强大的逼近能力和自适应性,已广泛应…...

3D基因组工具(HiC可视化)trackc--bioinfomatics tools 35
01 3D genome data analysis guides 茶树三维基因组-文献精读19 https://trackc.readthedocs.io/en/latest/install.html #官网 https://github.com/seqyuan/trackc #官网https://trackc.readthedocs.io/en/latest/analysis_guide/index.html #HiC可视化案例 …...

【大模型微调】图片转pdf
有时候图片需要转成pdf https://www.bilibili.com/opus/982151156821131282 https://help.pdf24.org/ https://www.bilibili.com/video/BV163v2eyEWo/?vd_source=8318f88fcdf4948d2b21fae7c9cf3184 2024最新!小白如何安装破解版的 Acrobat https://www.32r.com/zt/dgyjzzrj/ …...

Linux-Ubuntu16.04摄像头 客户端抓取帧并保存为PNG
1.0:client.c抓取帧并保存为PNG #include <stdio.h> // 标准输入输出库 #include <stdlib.h> // 标准库,包含内存分配等函数 #include <string.h> // 字符串操作库 #include <linux/videodev2.h> // V4L2 视频设备…...

手机ip地址取决于什么?可以随便改吗
手机IP地址是指手机在连接到互联网时所获得的唯一网络地址,这个地址由一串数字组成,用于在网络中标识和定位设备。每个设备在连接到网络时都会被分配一个IP地址,它可以帮助数据包在网络中准确地找到目标设备。那么,手机IP地址究竟…...

计算机网络:TCP/IP协议的五大重要特性介绍
目录 一、逻辑编址 二、路由选择 三、名称解析 四、错误控制和流量控制 五、多应用支持 今天给大家聊聊TCP/IP协议中五大重要特性相关的知识,希望对大家深入了解该协议提供一些帮助! 一、逻辑编址 首先要了解什么是物理地址、逻辑地址。 ●...

Java与AWS S3的文件操作
从零开始:Java与AWS S3的文件操作 一、什么是 AWS S3?AWS S3 的特点AWS S3 的应用场景 二、Java整合S3方法使用 MinIO 客户端操作 S3使用 AWS SDK 操作 S3 (推荐使用) 三、总结 一、什么是 AWS S3? Amazon Simple Sto…...

详解 YOLOv5 模型运行参数含义以及设置及在 PyCharm 中的配置方法
详解 YOLOv5 模型运行参数含义以及设置及在 PyCharm 中的配置方法 这段代码中使用的命令行参数允许用户在运行 YOLOv5 模型时自定义多种行为和设置。以下是各个参数的详细说明和使用示例,以及如何在 PyCharm 中设置这些参数以确保正确运行带有参数的脚本。 命令行…...

Vue根据Div内容的高度给其Div设置style height
在 Vue.js 中,你可以使用 JavaScript 来动态地根据 div 的内容高度来设置其 style 的 height 属性。这通常是在组件挂载或更新时完成的,因为这时你已经有了实际的 DOM 元素可以操作。 以下是一个简单的例子,展示了如何实现这一点:…...

驱动篇的开端
准备 在做之后的动作前,因为win7及其以上的版本默认是不支持DbgPrint(大家暂时理解为内核版的printf)的打印,所以,为了方便我们的调试,我们先要修改一下注册表 创建一个reg文件然后运行 Windows Registr…...

OpenSSL 自建CA 以及颁发证书(网站部署https双向认证)
前言 1、前面写过一篇 阿里云免费ssl证书申请与部署,大家可以去看下 一、openssl 安装说明 1、这部分就不再说了,我使用centos7.9,是自带 openssl的,window的话,要去下载安装 二、CA机构 CA机构,全称为…...

吾杯网络安全技能大赛WP(部分)
吾杯网络安全技能大赛WP(部分) MISC Sign 直接16进制解码即可 原神启动 将图片用StegSolve打开 找到了压缩包密码 将解出docx文件改为zip 找到了一张图片和zip 再把图片放到stegSlove里找到了img压缩包的密码 然后在document.xml里找到了text.zip压缩包密码 然后就出来fl…...

按vue组件实例类型实现非侵入式国际化多语言翻译
#vue3##国际化##本地化##international# web界面国际化,I18N(Internationalization,国际化),I11L(International,英特纳雄耐尔),L10N(Localization,本地化)&…...

Java入门:22.集合的特点,List,Set和Map集合的使用
1 什么是集合 本质就是容器的封装,可以存储多个元素 数组一旦创建,长度就不能再改变了。 数组一旦创建,存储内容的类型不能改变。 数组可以存储基本类型,也可以存储引用类型。 数组可以通过length获得容量的大小,但…...

重生之我在异世界学编程之C语言:深入指针篇(下)
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 目录 题集(1)指针笔试题1&a…...

理解Parquet文件和Arrow格式:从Hugging Face数据集的角度出发
parquet发音:美 [pɑrˈkeɪ] 镶木地板;拼花木地板 理解Parquet文件和Arrow格式:从Hugging Face数据集的角度出发 引言 在机器学习和大数据处理中,数据的存储和传输格式对于性能至关重要。两种广泛使用的格式是 Parquet 和 Arr…...

下载 M3U8 格式的视频
要下载 M3U8 格式的视频(通常是 HLS 视频流),可以尝试以下几种方法: 方法 1:使用下载工具(推荐) 1. IDM(Internet Download Manager): 安装 IDM 并启用浏…...

Tomcat使用教程
下载地址:https://tomcat.apache.org/ 配置环境变量 变量名: CATALINA_HOME 变量值: D:\tools\apache-tomcat-9.0.97 Path: %CATALINA_HOME%\bin 启动Tomcat(打开命令提示符) startup.bat 解决乱码问题(打开conf\logging.properties) java.util.logging.Conso…...

LabVIEW氢气纯化控制系统
基于LabVIEW的氢气纯化控制系统满足氢气纯化过程中对精确控制的需求,具备参数设置、过程监控、数据记录和报警功能,体现了LabVIEW在复杂工业控制系统中的应用效能。 项目背景 在众多行业中,尤其是石油化工和航天航空领域,氢气作为…...

现在的电商风口已经很明显了
随着电商行业的不断发展,直播带货的热潮似乎正逐渐降温,而货架电商正成为新的焦点。抖音等平台越来越重视货架电商,强调搜索功能的重要性,预示着未来的电商中心将转向货架和搜索。 在这一转型期,AI技术与电商的结合为…...

Uniapp触底刷新
在你的代码中,使用了 scroll-view 来实现一个可滚动的评论区域,并且通过监听 scrolltolower 事件来触发 handleScrollToLower 函数,以实现“触底更新”或加载更多评论的功能。 关键部分分析: scroll-view 组件: scroll-view 是一…...

开源项目 - face parsing 人脸区域分割 人像区域分割 人脸分割 人像区域分割 BiSeNet
开源项目 - face parsing 人脸区域分割 人像区域分割 人脸分割 人像区域分割 BiSeNet 项目地址:GitHub - XIAN-HHappy/face_parsing: face_parsing 脸部分割 示例: 助力快速掌握数据集的信息和使用方式。 数据可以如此美好!...

python游戏设计---飞机大战
1.前言 上次做飞机大战游戏有人这么说: 好好好!今天必须整一个,今天我们来详细讲解一下,底部找素材文件下载!!! 2.游戏制作 目录如下: 1.导入的包 import pygame import sys imp…...