使用Docker 部署 LNMP+Redis 环境
使用Docker 部署 LNMP+Redis 环境
Docker 简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。推荐内核版本3.8及以上
为什么使用Docker
- 加速本地的开发和构建流程,容器可以在开发环境构建,然后轻松地提交到测试环境,并最终进入生产环境
- 能够在让独立的服务或应用程序在不同的环境中得到相同的运行结果
- 创建隔离的环境来进行测试
- 高性能、超大规划的宿主机部署
- 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境
目录
- 安装Docker
- 目录结构
- 快速使用
- 进入容器内部
- PHP扩展安装
- Composer安装
- 常见问题处理
- 常用命令
- Dockerfile语法
- docker-compose语法说明
项目源码地址: GitHub
安装Docker
windows 安装
参考
mac
docker toolbox参考
linux
# 下载安装
curl -sSL https://get.docker.com/ | sh# 设置开机自启
sudo systemctl enable docker.servicesudo service docker start|restart|stop# 安装docker-compose
curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
目录结构
docker_lnmp
├── v2
├── mysql
│ └── Dockerfile
│ └── my.cnf
├── nginx
│ ├── Dockerfile
│ ├── nginx.conf
│ ├── log
│ │ └── error.log
│ └── www
│ ├── index.html
│ ├── index.php
│ ├── db.php
│ └── redis.php
├── php
│ ├── Dockerfile
│ ├── www.conf
│ ├── php-fpm.conf
│ ├── php.ini
│ └── log
│ └── php-fpm.log
└── redis└── Dockerfile└── redis.conf
创建镜像与安装
直接使用docker-compose一键制作镜像并启动容器
版本一
该版本是通过拉取纯净的CentOS镜像,通过Dockerfile相关命令进行源码编译安装各个服务。所以该方式很方便定制自己需要的镜像,但是占用空间大且构建慢。
git clone https://github.com/voocel/docker-lnmp.git
cd docker-lnmp
docker-compose up -d
版本二(推荐)
git clone https://github.com/voocel/docker-lnmp.git
cd docker-lnmp/v2
chmod 777 ./redis/redis.log
chmod -R 777 ./redis/data
docker-compose up -d
该版本是通过拉取官方已经制作好的各个服务的镜像,再通过Dockerfile相关命令根据自身需求做相应的调整。所以该方式构建迅速使用方便,因为是基于Alpine Linux所以占用空间很小。
测试
使用docker ps查看容器启动状态,若全部正常启动了则
通过访问127.0.0.1、127.0.0.1/index.php、127.0.0.1/db.php、127.0.0.1/redis.php 即可完成测试
(若想使用https则请修改nginx下的dockerfile,和nginx.conf按提示去掉注释即可,灵需要在ssl文件夹中加入自己的证书文件,本项目自带的是空的,需要自己替换,保持文件名一致)
进入容器内部
- 使用 docker exec
docker exec -it ngixn /bin/sh
- 使用nsenter命令
# cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;
# ./configure --without-ncurses
# make nsenter && sudo cp nsenter /usr/local/bin
为了连接到容器,你还需要找到容器的第一个进程的 PID,可以通过下面的命令获取再执行。
PID=$(docker inspect --format "{{ .State.Pid }}" container_id)
# nsenter --target $PID --mount --uts --ipc --net --pid
PHP扩展安装
- 安装PHP官方源码包里的扩展(如:同时安装pdo_mysql mysqli pcntl gd四个个扩展)
在php的Dockerfile中加入以下命令
RUN apk add libpng-dev \&& docker-php-ext-install pdo_mysql mysqli pcntl gd \
注:因为该镜像缺少gd库所需的libpng-dev包,所以需要先下载这个包
- PECL 扩展安装
# 安装扩展
RUN pecl install memcached-2.2.0 \# 启用扩展&& docker-php-ext-enable memcached \
- 通过下载扩展源码,编译安装的方式安装
# 安装Redis和swoole扩展
RUN cd ~ \&& wget https://github.com/phpredis/phpredis/archive/4.2.0.tar.gz \&& tar -zxvf 4.2.0.tar.gz \&& mkdir -p /usr/src/php/ext \&& mv phpredis-4.2.0 /usr/src/php/ext/redis \&& docker-php-ext-install redis \&& apk add libstdc++\&& cd ~ \&& wget https://github.com/swoole/swoole-src/archive/v4.2.12.tar.gz \&& tar -zxvf v4.2.12.tar.gz \&& mkdir -p /usr/src/php/ext \&& mv swoole-src-4.2.12 /usr/src/php/ext/swoole \&& docker-php-ext-install swoole \
注:因为该镜像需要先安装swoole依赖的libstdc++,否则安装成功后无法正常加载swoole扩展
Composer安装
在Dockerfile中加入
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
常见问题处理
- redis启动失败问题
在v2版本中redis的启动用户为redis不是root,所以在宿主机中挂载的./redis/redis.log和./redis/data需要有写入权限。
chmod 777 ./redis/redis.logchmod 777 ./redis/data
- MYSQL连接失败问题
在v2版本中是最新的MySQL8,而该版本的密码认证方式为Caching_sha2_password,而低版本的php和mysql可视化工具可能不支持,可通过phpinfo里的mysqlnd的Loaded plugins查看是否支持该认证方式,否则需要修改为原来的认证方式mysql_native_password:
select user,host,plugin,authentication_string from mysql.user;ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';FLUSH PRIVILEGES;
-
注意挂载目录的权限问题,不然容器成功启动几秒后立刻关闭,例:以下/data/run/mysql 目录没权限的情况下就会出现刚才那种情况
docker run --name mysql57 -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -v /data/logs/mysql:/var/log/mysql -v /data/run/mysql:/var/run/mysqld -e MYSQL_ROOT_PASSWORD=123456 -it centos/mysql:v5.7
-
需要注意php.ini 中的目录对应 mysql 的配置的目录需要挂载才能获取文件内容,不然php连接mysql失败
# php.ini mysql.default_socket = /data/run/mysql/mysqld.sock mysqli.default_socket = /data/run/mysql/mysqld.sock pdo_mysql.default_socket = /data/run/mysql/mysqld.sock# mysqld.cnf pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock
-
使用php连接不上redis
# 错误的 $redis = new Redis; $rs = $redis->connect('127.0.0.1', 6379);
php连接不上,查看错误日志
PHP Fatal error: Uncaught RedisException: Redis server went away in /www/index.php:7
考虑到docker 之间的通信应该不可以用127.0.0.1 应该使用容器里面的ip,所以查看redis 容器的ip
[root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b5f7dcecff4c docker_nginx "/usr/sbin/nginx -..." 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp nginx 60fd2df36d0e docker_php "/usr/local/php/sb..." 7 seconds ago Up 5 seconds 9000/tcp php 7c7df6f8eb91 hub.c.163.com/library/mysql:latest "docker-entrypoint..." 12 seconds ago Up 11 seconds 3306/tcp mysql a0ebd39f0f64 docker_redis "usr/local/redis/s..." 13 seconds ago Up 12 seconds 6379/tcp redis
注意测试的时候连接地址需要容器的ip或者容器名names,比如redis、mysql.
例如nginx配置php文件解析 fastcgi_pass php:9000;
例如php连接redis $redis = new Redis;$res = $redis->connect('redis', 6379);因为容器ip是动态的,重启之后就会变化,所以可以创建静态ip
第一步:创建自定义网络
#备注:这里选取了172.172.0.0网段,也可以指定其他任意空闲的网段 docker network create --subnet=172.171.0.0/16 docker-at docker run --name redis326 --net docker-at --ip 172.171.0.20 -d -p 6379:6379 -v /data:/data -it centos/redis:v3.2.6
连接redis 就可以配置对应的ip地址了,连接成功
$redis = new Redis; $rs = $redis->connect('172.171.0.20', 6379);
另外还有种可能phpredis连接不上redis,需要把redis.conf配置略作修改。
bind 127.0.0.1 改为: bind 0.0.0.0
- 启动docker web服务时 虚拟机端口转发 外部无法访问 一般出现在yum update的时候(WARNING: IPv4 forwarding is disabled. Networking will not work.)或者宿主机可以访问,但外部无法访问
vi /etc/sysctl.conf
或者
vi /usr/lib/sysctl.d/00-system.conf
添加如下代码:net.ipv4.ip_forward=1重启network服务
systemctl restart network查看是否修改成功
sysctl net.ipv4.ip_forward如果返回为"net.ipv4.ip_forward = 1"则表示成功了
- 如果使用最新的MySQL8无法正常连接,由于最新版本的密码加密方式改变,导致无法远程连接。
# 修改密码加密方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
常用命令
docker start
容器名(容器ID也可以)docker stop
容器名(容器ID也可以)docker run
命令加 -d 参数,docker 会将容器放到后台运行docker ps
正在运行的容器docker logs
--tail 10 -tf 容器名 查看容器的日志文件,加-t是加上时间戳,f是跟踪某个容器的最新日志而不必读整个日志文件docker top
容器名 查看容器内部运行的进程docker exec -d
容器名 touch /etc/new_config_file 通过后台命令创建一个空文件docker run --restart=always --name
容器名 -d ubuntu /bin/sh -c "while true;do echo hello world; sleep 1; done" 无论退出代码是什么,docker都会自动重启容器,可以设置 --restart=on-failure:5 自动重启的次数docker inspect
容器名 对容器进行详细的检查,可以加 --format='{(.State.Running)}' 来获取指定的信息docker rm
容器ID 删除容器,注,运行中的容器无法删除docker rm $(docker ps -aq)
删除所有容器docker rmi $(docker images -aq)
删除所有镜像docker images
列出镜像docker pull
镜像名:标签 拉镜像docker search
查找docker Hub 上公共的可用镜像docker build -t='AT/web_server:v1'
命令后面可以直接加上github仓库的要目录下存在的Dockerfile文件。 命令是编写Dockerfile 之后使用的。-t选项为新镜像设置了仓库和名称:标签docker login
登陆到Docker Hub,个人认证信息将会保存到$HOME/.dockercfg,docker commit -m="comment " --author="AT"
容器ID 镜像的用户名/仓库名:标签 不推荐这种方法,推荐dockerfiledocker history
镜像ID 深入探求镜像是如何构建出来的docker port
镜像ID 端口 查看映射情况的容器的ID和容器的端口号,假设查询80端口对应的映射的端口run
运行一个容器, -p 8080:80 将容器内的80端口映射到docker宿主机的某一特定端口,将容器的80端口绑定到宿主机的8080端口,另 127.0.0.1:80:80 是将容器的80端口绑定到宿主机这个IP的80端口上,-P 是将容器内的80端口对本地的宿主机公开- http://docs.docker.com/refere... 查看更多的命令
docker push
镜像名 将镜像推送到 Docker Hubdocker rmi
镜像名 删除镜像docker attach
容器ID 进入容器docker network create --subnet=172.171.0.0/16 docker-at
选取172.172.0.0网段docker build
就可以加 -ip指定容器ip 172.171.0.10 了
删除所有容器和镜像的命令
docker rm `docker ps -a |awk '{print $1}' | grep [0-9a-z]` 删除停止的容器
docker rmi $(docker images | awk '/^<none>/ { print $3 }')
Dockerfile语法
MAINTAINER
标识镜像的作者和联系方式EXPOSE
可以指定多个EXPOSE向外部公开多个端口,可以帮助多个容器链接FROM
指令指定一个已经存在的镜像\#
号代表注释RUN
运行命令,会在shell 里使用命令包装器 /bin/sh -c 来执行。如果是在一个不支持shell 的平台上运行或者不希望在shell 中运行,也可以 使用exec 格式 的RUN指令ENV REFRESHED_AT
环境变量 这个环境亦是用来表明镜像模板最后的更新时间VOLUME
容器添加卷。一个卷是可以 存在于一个或多个容器内的特定的目录,对卷的修改是立刻生效的,对卷的修改不会对更新镜像产品影响,例:VOLUME["/opt/project","/data"]ADD
将构建环境 下的文件 和目录复制到镜像 中。例 ADD nginx.conf /conf/nginx.conf 也可以是取url 的地址文件,如果是压缩包,ADD命令会自动解压、USER
指定镜像用那个USER 去运行COPY
是复制本地文件,而不会去做文件提取(解压包不会自动解压) 例:COPY conf.d/ /etc/apache2/ 将本地conf.d目录中的文件复制到/etc/apache2/目录中
docker-compose.yml 语法说明
image
指定为镜像名称或镜像ID。如果镜像不存在,Compose将尝试从互联网拉取这个镜像build
指定Dockerfile所在文件夹的路径。Compose将会利用他自动构建这个镜像,然后使用这个镜像command
覆盖容器启动后默认执行的命令links
链接到其他服务容器,使用服务名称(同时作为别名)或服务别名(SERVICE:ALIAS)都可以external_links
链接到docker-compose.yml外部的容器,甚至并非是Compose管理的容器。参数格式和links类似ports
暴露端口信息。宿主机器端口:容器端口(HOST:CONTAINER)格式或者仅仅指定容器的端口(宿主机器将会随机分配端口)都可以(注意:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 你可能会得到错误得结果,因为 YAML 将会解析 xx:yy 这种数字格式为 60 进制。所以建议采用字符串格式。)expose
暴露端口,与posts不同的是expose只可以暴露端口而不能映射到主机,只供外部服务连接使用;仅可以指定内部端口为参数volumes
设置卷挂载的路径。可以设置宿主机路径:容器路径(host:container)或加上访问模式(host:container:ro)ro就是readonly的意思,只读模式volunes_from
挂载另一个服务或容器的所有数据卷environment
设置环境变量。可以属于数组或字典两种格式。如果只给定变量的名称则会自动加载它在Compose主机上的值,可以用来防止泄露不必要的数据env_file
从文件中获取环境变量,可以为单独的文件路径或列表。如果通过docker-compose -f FILE指定了模板文件,则env_file中路径会基于模板文件路径。如果有变量名称与environment指令冲突,则以后者为准(环境变量文件中每一行都必须有注释,支持#开头的注释行)extends
基于已有的服务进行服务扩展。例如我们已经有了一个webapp服务,模板文件为common.yml。编写一个新的 development.yml 文件,使用 common.yml 中的 webapp 服务进行扩展。后者会自动继承common.yml中的webapp服务及相关的环境变量net
设置网络模式。使用和docker client 的 --net 参数一样的值pid
和宿主机系统共享进程命名空间,打开该选项的容器可以相互通过进程id来访问和操作dns
配置DNS服务器。可以是一个值,也可以是一个列表cap_add,cap_drop
添加或放弃容器的Linux能力(Capability)dns_search
配置DNS搜索域。可以是一个值也可以是一个列表- 注意:使用compose对Docker容器进行编排管理时,需要编写docker-compose.yml文件,初次编写时,容易遇到一些比较低级的问题,导致执行docker-compose up时先解析yml文件的错误。比较常见的是yml对缩进的严格要求。yml文件还行后的缩进,不允许使用tab键字符,只能使用空格,而空格的数量也有要求,一般两个空格。
项目源码地址: GitHub
phpdockernginx
相关文章:
使用Docker 部署 LNMP+Redis 环境
使用Docker 部署 LNMPRedis 环境 Docker 简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互…...
文件上传漏洞学习笔记
一、漏洞概述 定义 文件上传漏洞指未对用户上传的文件进行充分安全校验,导致攻击者可上传恶意文件(如Webshell、木马),进而控制服务器或执行任意代码。 危害等级 ⚠️ 高危漏洞(通常CVSS评分7.0)ÿ…...
375_C++_cloud手机推送,添加人脸告警信息到任务队列中,UploadAlarmPush是典型的工厂模式应用,为什么使用工厂模式完成这部分代码
一:AlarmFaceInfo的应用 让我帮你解析这个lambda表达式的实现: // ...................... .h ...........................// struct RsMsgPushTask_S : public Task{AlarmType_E mainAlarmType;unsigned int subAlarmType;DateTime alarmTime...
Spring Boot 中的日志管理
一、日志框架选择 1. 主流框架对比 框架特点Spring Boot 默认支持Logback- 性能优异,Spring Boot 默认集成- 支持自动热更新配置文件✅ (默认)Log4j2- 异步日志性能更强- 支持插件扩展- 防范漏洞能力更好❌ (需手动配置)JUL (JDK自带)- 无需额外依赖- 功能简单&am…...

火绒终端安全管理系统V2.0网络防御功能介绍
火绒终端安全管理系统V2.0 【火绒企业版V2.0】网络防御功能包含网络入侵拦截、横向渗透防护、对外攻击检测、僵尸网络防护、Web服务保护、暴破攻击防护、远程登录防护、恶意网址拦截。火绒企业版V2.0的网络防御功能,多层次、多方位,守护用户终端安全。 …...

海康摄像头 + M7s(Monibuca) + FFmpeg + Python实现多个网络摄像头视频流推流
最近在研究流媒体服务器时,我注意到了一款开源软件——M7s。按照官网的指南部署完成后,我开始进行测试,发现单视频流推送非常顺利,没有任何问题。然而,当我尝试进行多视频流推送时,却发现网上的相关教程寥寥…...
抖音视频如何下载保存去水印
随着短视频平台的兴起,抖音作为国内最受欢迎的短视频平台之一,吸引了大量用户上传和观看各种创意视频。许多用户在浏览抖音视频时,往往会想要保存一些有趣或精彩的视频片段,但抖音视频通常会有水印,影响观看体验。为了…...

【鸿蒙开发】第三十九章 LazyForEach:数据懒加载
目录 1 背景 2 使用限制 键值生成规则 组件创建规则 首次渲染 非首次渲染 改变数据子属性 使用状态管理V2 拖拽排序 1 背景 LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach,框架…...

HTTP-
一.HTTP 1.什么是HTTP HTTP(超文本传输协议)是一种工作在应用层的协议.主要用于网站,就是浏览器和服务器之间的数据传输. 小知识:什么是超文本传输协议 文本:是字符串.(能在utf8/gbk码表上找到合法字符) 超文本:不仅可以传输字符串,也可以传输图片,html等 富文本:word文档 2.HT…...
创建型模式 - 原型模式 (Prototype Pattern)
创建型模式 -原型模式 (Prototype Pattern) 它允许通过复制现有对象来创建新对象,而无需知道对象的具体创建细节。在 Java 中,可以通过实现 Cloneable 接口和重写 clone() 方法来实现原型模式。 有深、浅两种克隆 类实现 Cloneable 接口就可以深克隆如果…...
Android 8.0 (API 26) 对广播机制做了哪些变化
大部分隐式广播无法通过静态注册接收,除了以下白名单广播: ACTION_BOOT_COMPLETED ACTION_TIMEZONE_CHANGED ACTION_LOCALE_CHANGED ACTION_MY_PACKAGE_REPLACED ACTION_PACKAGE_ADDED ACTION_PACKAGE_REMOVED 需要以动态注册方案替换: cl…...

Unity汽车笔记
汽车的移动和转向 我们知道,汽车的前进后退是变速运动。按w,汽车开始加速,到最大速度后保持匀速,松开w,汽车受到阻力加速。如果按s减速,则以更大的加速度减速。后退反之。 按A/D时前轮偏转。只有前进后退…...
html中rel、href、src、url的区别
1.url url(统一资源定位符):是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。 2.href href:Hypertext Reference的缩写。 意思是超文本引用。 3.rel rel:relatio…...
【idea问题排查技巧】
以下是针对 IDEA 中 日志打标(动态标记) 和 全链路追踪 功能的分步详解,结合具体场景和操作截图说明,帮助快速掌握实战技巧。 一、动态日志打标:不修改代码输出关键信息 1. 断点日志打印(非侵入式打标) 场景:在调试时,需要临时查看某个变量的值,但不想修改代码添加…...

SQL: DDL,DML,DCL,DTL,TCL,
Structured Query Language,结构化查询语言, 是一种用于管理和操作关系数据库的标准编程语言。 sql的分类 DQL(Data Query Language):数据查询语言 DDL(Data Definition Language):数据定义语…...
WordPress R+L Carrier Edition sql注入漏洞复现(CVE-2024-13481)(附脚本)
免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...
DeepSeek基础之机器学习
文章目录 一、核心概念总结(一)机器学习基本定义(二)基本术语(三)假设空间(四)归纳偏好(五)“没有免费的午餐”定理(NFL 定理) 二、重…...

QSplashScreen --软件启动前的交互
目录 QSplashScreen 类介绍 使用方式 项目中使用 THPrinterSplashScreen头文件 THPrinterSplashScreen实现代码 使用代码 使用效果 QSplashScreen 类介绍 QSplashScreen 是 Qt 中的一个类,用于显示启动画面。它通常在应用程序启动时显示,以向用户显…...
Python 循环嵌套
Python 循环嵌套 引言 在编程语言中,循环嵌套是一种常见且强大的编程技术。它允许开发者重复执行一段代码块,并在每个循环迭代中执行另一个循环。在Python中,循环嵌套广泛应用于数据分析和算法实现等领域。本文将详细介绍Python循环嵌套的概念、语法以及应用场景。 循环嵌…...

性能测试项目实战
项目介绍和部署 项目背景 轻商城项目是一个现在流行的电商项目。我们需要综合评估该项目中各个关键接口的性能,并给出优化建议,以满足项目上线后的性能需要。 项目功能架构 前台商城:购物车、订单、支付、优惠券等 后台管理系统:商…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...