MySQL高可用管理工具:orchestrator

article/2025/8/23 16:20:40

orchestrator 是一个MySQL高可用复制拓补的管理和可视化工具,同时也是GitHub官方在使用的一个复制拓补管理工具,它允许:

1)发现:

orchestrator主动发现拓补结构并读取基本的MySQL信息,如复制状态和配置。

2)重构:

可以将一个不可用的服务器从拓补结构中剔除,并把数据副本移动到另一个从库下面

3)恢复:

在不可用时,可以选择一个适合的从库提升为主库

4)可视化:

web可视化,并允许直接在界面上进行复制拓补变更等操作

GitHub链接地址:https://github.com/github/orchestrator

一、环境:

系统:

        centos7.2

三台主机:

        master:192.168.89.100

        slave1:192.168.89.102

        slave2:192.168.89.103

后端端口: 

          orchestrator实例端口:3306   三节点开启raft保证orchestrator自身高可用性。

   后端mysql服务器实例端口:3307

二、安装:

开启raft时需要关闭IPV6。关闭selinux。

1)安装yum扩展源:yum -y install epel-release

2)更新系统上的软件:yum -y update

3)安装依赖:yum install -y jq oniguruma oniguruma-devel

4)下载服务端和客户端的软件包:

      wget https://github.com/github/orchestrator/releases/download/v3.0.14/orchestrator-3.0.14-1.x86_64.rpm
      wget https://github.com/github/orchestrator/releases/download/v3.0.14/orchestrator-client-3.0.14-1.x86_64.rpm

5)安装:yum localinstall -y orchestrator*.rpm

6)安装后,自动在/usr/local下创建orchestrator目录。

orchestrator:执行程序。

*.conf.json:配置文件模板。

resources:web,伪GTID相关文件

7)配置文件直接使用自带的模板文件:cp -a orchestrator-sample.conf.json orchestrator.conf.json

8)配置文件参数说明:

{
  "Debug": true,     #debug模式,输出详细信息
  "EnableSyslog": false,   #是否输出到系统日志里
  "ListenAddress": ":3000",   #orchestrator的监听端口,web端口
  "MySQLTopologyUser": "failover",   #后端被管理的mysql实例中的账号,所有实例都要有,本次为3307端口
  "MySQLTopologyPassword": "123456",   #密码
  "MySQLTopologyCredentialsConfigFile": "",   #验证的配置文件,账号密码可以直接写入文件,读取
  "MySQLTopologySSLPrivateKeyFile": "",   #ssl验证文件
  "MySQLTopologySSLCertFile": "",
  "MySQLTopologySSLCAFile": "",
  "MySQLTopologySSLSkipVerify": true,   #跳过验证
  "MySQLTopologyUseMutualTLS": false,   #使用TLS验证
  "MySQLOrchestratorHost": "127.0.0.1",   #orchestrator的IP,也可以是本机IP
  "MySQLOrchestratorPort": 3306,   #orchestrator所在的端口,本次为3306端口
  "MySQLOrchestratorDatabase": "orchestrator",   #orchestrator元数据的数据库名称
  "MySQLOrchestratorUser": "root",   #管理orchestrator数据库的账户
  "MySQLOrchestratorPassword": "123456",  #密码
  "MySQLOrchestratorCredentialsConfigFile": "",
  "MySQLOrchestratorSSLPrivateKeyFile": "",
  "MySQLOrchestratorSSLCertFile": "",
  "MySQLOrchestratorSSLCAFile": "",
  "MySQLOrchestratorSSLSkipVerify": true,
  "MySQLOrchestratorUseMutualTLS": false,
  "MySQLConnectTimeoutSeconds": 1,   #orchestrator连接mysql超时秒数
  "DefaultInstancePort": 3307,  #mysql实例的端口,本次为3307,对外提供服务的实例
  "DiscoverByShowSlaveHosts": true,   #是否启用审查和自动发现
  "InstancePollSeconds": 5,   #orchestrator探测mysql间隔秒数

  "SkipMaxScaleCheck": true,    #没有MaxScale binlogserver设置为true

  "UnseenInstanceForgetHours": 240,   #忘记看不见的实例的小时数
  "SnapshotTopologiesIntervalHours": 0,   #快照拓扑调用之间的小时间隔。默认值:0(禁用)
  "InstanceBulkOperationsWaitTimeoutSeconds": 10,   #执行批量(多个实例)操作时在单个实例上等待的时间
  "HostnameResolveMethod": "none",  #解析主机名,默认default   不解析为none
  "MySQLHostnameResolveMethod": "@@hostname",
  "SkipBinlogServerUnresolveCheck": true,  #跳过二进制服务器检测
  "ExpiryHostnameResolvesMinutes": 60,  #域名检测过期分钟数
  "RejectHostnameResolvePattern": "",   #禁止的域名正则表达式
  "ReasonableReplicationLagSeconds": 10,    #复制延迟高于10秒表示异常
  "ProblemIgnoreHostnameFilters": [],  #主机正则匹配筛选最小化
  "VerifyReplicationFilters": false,  #重构钱检查复制筛选器
  "ReasonableMaintenanceReplicationLagSeconds": 20,   #上移和下移的阈值
  "CandidateInstanceExpireMinutes": 60,  #实例过期分钟数
  "AuditLogFile": "",  #审计日志
  "AuditToSyslog": false,  #审计日志输出到系统日志
  "RemoveTextFromHostnameDisplay": ":3306",  #去除集群的文本
  "ReadOnly": true,  #全局只读
  "AuthenticationMethod": "",  #身份验证模式
  "HTTPAuthUser": "",  #http验证用户名
  "HTTPAuthPassword": "",  #http验证密码
  "AuthUserHeader": "",   #指示身份验证用户的HTTP标头,当AuthenticationMethod为“proxy”时
  "PowerAuthUsers": [   #在AuthenticationMethod ==“proxy”上,可以进行更改的用户列表。所有其他都是只读的。
    "*"
  ],
  "ClusterNameToAlias": {  #正则表达式匹配群集名称与人类友好别名之间的映射
    "127.0.0.1": "test suite"
  },
  "SlaveLagQuery": "",  #使用SHOW SLAVE STATUS进行延迟判断
  "DetectClusterAliasQuery": "SELECT SUBSTRING_INDEX(@@hostname, '.', 1)",  #查询集群别名
  "DetectClusterDomainQuery": "",  #可选查询(在拓扑实例上执行),返回此集群主服务器的VIP / CNAME /别名/任何域名。查询将仅在集群主机上执行(尽管在拓扑的主机被重新调用之前,它可以在其他/所有副本上执行)。如果提供,必须返回一行,一列
  "DetectInstanceAliasQuery": "",  #可选查询(在拓扑实例上执行),返回实例的别名。如果提供,必须返回一行,一列
  "DetectPromotionRuleQuery": "",  #可选查询(在拓扑实例上执行),返回实例的提升规则。如果提供,必须返回一行,一列。
  "DataCenterPattern": "[.]([^.]+)[.][^.]+[.]mydomain[.]com",   #从正则表达式中筛选数据中心名称
  "PhysicalEnvironmentPattern": "[.]([^.]+[.][^.]+)[.]mydomain[.]com",  #返回实例的物理环境
  "PromotionIgnoreHostnameFilters": [],   #Orchestrator不会使用主机名匹配模式来提升副本(通过-c recovery;例如,避免使用dev专用计算机)
  "DetectSemiSyncEnforcedQuery": "",  #查询以确定是否强制完全半同步写入
  "ServeAgentsHttp": false,  #产生一个agent的http接口
  "AgentsServerPort": ":3001",  #可选,对于raft设置,此节点将向其对等方通告的HTTP地址是什么(可能在NAT后面或重新路由端口时使用;例如:“http://11.22.33.44:3030”)
  "AgentsUseSSL": false,  #当“true”orchestrator将使用SSL侦听代理端口以及通过SSL连接到代理时
  "AgentsUseMutualTLS": false,
  "AgentSSLSkipVerify": false,
  "AgentSSLPrivateKeyFile": "",
  "AgentSSLCertFile": "",
  "AgentSSLCAFile": "",
  "AgentSSLValidOUs": [],
  "UseSSL": false,  #在服务器Web端口上使用SSL
  "UseMutualTLS": false,
  "SSLSkipVerify": false,
  "SSLPrivateKeyFile": "",
  "SSLCertFile": "",
  "SSLCAFile": "",
  "SSLValidOUs": [],
  "URLPrefix": "",  #在非根Web路径上运行orchestrator的URL前缀,例如/ orchestrator将其置于nginx之后。
  "StatusEndpoint": "/api/status",  #使用相互TLS时的有效组织单位
  "StatusSimpleHealth": true,
  "StatusOUVerify": false,
  "AgentPollMinutes": 60,  #代理轮询之间的分钟数
  "UnseenAgentForgetHours": 6,  #忘记看不见代理的小时数
  "StaleSeedFailMinutes": 60,  #认为陈旧(无进展)种子失败的分钟数。
  "SeedAcceptableBytesDiff": 8192,  #仍被视为成功复制的种子源和目标数据大小之间的字节数差异
  "PseudoGTIDPattern": "",  #为空禁用伪GTID
  "PseudoGTIDPatternIsFixedSubstring": false, #如果为true,则PseudoGTIDPattern不被视为正则表达式而是固定子字符串,并且可以提高搜索时间
  "PseudoGTIDMonotonicHint": "asc:",  #Pseudo-GTID条目中的字符串,表示Pseudo-GTID条目预计会单调递增
  "DetectPseudoGTIDQuery": "",  #可选查询,用于权威地决定是否在实例上启用伪gtid
  "BinlogEventsChunkSize": 10000,  #SHOW BINLOG的块大小(X)| RELAYLOG EVENTS LIMIT?,X语句。较小意味着更少的锁定和工作要做
  "SkipBinlogEventsContaining": [],  #扫描/比较Pseudo-GTID的binlog 时,跳过包含给定文本的条目。这些不是正则表达式(扫描binlog时会消耗太多的CPU),只需查找子字符串。
  "ReduceReplicationAnalysisCount": true,  #当为true时,复制分析将仅报告可能首先处理问题的可能性的实例(例如,不报告大多数叶子节点,这些实际上是无趣的)。如果为false,则为每个已知实例提供一个条目
  "FailureDetectionPeriodBlockMinutes": 60,   #该时间内发现故障,不被多次发现
  "RecoveryPeriodBlockSeconds": 3600,   #该时间内发现故障,不会多次转移
  "RecoveryIgnoreHostnameFilters": [],  #恢复会忽略的主机
  "RecoverMasterClusterFilters": [   #仅在匹配这些正则表达式模式的集群上进行主恢复(当然“。*”模式匹配所有内容)
    "*"
  ],
  "RecoverIntermediateMasterClusterFilters": [   #仅在与这些正则表达式模式匹配的集群上进行IM恢复(当然“。*”模式匹配所有内容)
    "*"
  ],

#OnFailureDetectionProcesses:检测故障转移方案时执行的进程(在决定是否进行故障转移之前)。可以并且应该使用其中一些占位符:{failureType},{failureDescription},{command},{failedHost},{failureCluster},{failureClusterAlias},{failureClusterDomain},{failedPort},{successorHost},{successorPort},{ successorAlias},{countReplicas},{replicaHosts},{isDowntimed},{autoMasterRecovery},{autoIntermediateMasterRecovery}
  "OnFailureDetectionProcesses": [   
    "echo 'Detected {failureType} on {failureCluster}. Affected replicas: {countSlaves}  autoMasterRecovery:  {autoMasterRecovery}  losthost: {lostSlaves}  slavehost: {slaveHosts}   orchestratorHost: {orchestratorHost}' >> /tmp/recovery.log"
  ],

#PreGracefulTakeoverProcesses:在执行故障转移之前执行的进程(中止操作应该是任何一次以非零代码退出;执行顺序未定义)。可以并且应该使用其中一些占位符:{failureType},{failureDescription},{command},{failedHost},{failureCluster},{failureClusterAlias},{failureClusterDomain},{failedPort},{countReplicas},{replicaHosts},{ isDowntimed}
  "PreGracefulTakeoverProcesses": [   
    "echo 'Planned takeover about to take place on {failureCluster}. Master will switch to read_only autoMasterRecovery:  {autoMasterRecovery}  losthost: {lostSlaves}  slavehost: {slaveHosts}   orchestratorHost: {orchestratorHost}' >> /tmp/recovery.log"
  ],

#PreFailoverProcesses:在执行故障转移之前执行的进程(中止操作应该是任何一次以非零代码退出;执行顺序未定义)。可以并且应该使用其中一些占位符:{failureType},{failureDescription},{command},{failedHost},{failureCluster},{failureClusterAlias},{failureClusterDomain},{failedPort},{countReplicas},{replicaHosts},{ isDowntimed}
  "PreFailoverProcesses": [  #执行恢复操作前执行
    "echo 'Will recover from {failureType} on {failureCluster}' >> /tmp/recovery.log"
  ],

#PostFailoverProcesses:执行故障转移后执行的进程(执行顺序未定义)。可以并且应该使用其中一些占位符:{failureType},{failureDescription},{command},{failedHost},{failureCluster},{failureClusterAlias},{failureClusterDomain},{failedPort},{successorHost},{successorPort},{ successorAlias},{countReplicas},{replicaHosts},{isDowntimed},{isSuccessful},{lostReplicas},{countLostReplicas}
  "PostFailoverProcesses": [  
    "echo '(for all types) Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Successor: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],

#PostUnsuccessfulFailoverProcesses:在未完全成功的故障转移后执行的进程(执行顺序未定义)。可以并且应该使用其中一些占位符:{failureType},{failureDescription},{command},{failedHost},{failureCluster},{failureClusterAlias},{failureClusterDomain},{failedPort},{successorHost},{successorPort},{ successorAlias},{countReplicas},{replicaHosts},{isDowntimed},{isSuccessful},{lostReplicas},{countLostReplicas}
  "PostUnsuccessfulFailoverProcesses": [],  

#PostMasterFailoverProcesses:执行主故障转移后执行的进程(执行顺序未定义)。使用与PostFailoverProcesses相同的占位符
  "PostMasterFailoverProcesses": [ 
    "echo 'Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Promoted: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],

#PostIntermediateMasterFailoverProcesses:执行主故障转移后执行的进程(执行顺序未定义)。使用与PostFailoverProcesses相同的占位符
  "PostIntermediateMasterFailoverProcesses": [  #成功的中间主恢复时执行
    "echo 'Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Successor: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],

#PostGracefulTakeoverProcesses:在运行正常的主接管后执行的进程。使用与PostFailoverProcesses相同的占位符
  "PostGracefulTakeoverProcesses": [   #旧主位于新主之后执行
    "echo 'Planned takeover complete' >> /tmp/recovery.log"
  ],
  "CoMasterRecoveryMustPromoteOtherCoMaster": true,  #当'false'时,任何东西都可以升级(候选人优先于其他人)。当'为'时,orchestrator将促进其他共同主人或否则失败
  "DetachLostSlavesAfterMasterFailover": true,  #恢复可能丢失一些副本DetachLostReplicasAfterMasterFailover的同义词
  "ApplyMySQLPromotionAfterMasterFailover": true,  #orchestrator应该自己应用MySQL主促销:设置read_only = 0,分离复制等。
  "PreventCrossDataCenterMasterFailover": false,  #当为true(默认值:false)时,不允许跨DC主故障转移,orchestrator将尽其所能只在同一DC内进行故障转移,否则根本不进行故障转移。
  "MasterFailoverDetachSlaveMasterHost": false,   #确保新主不复制旧主的数据MasterFailoverDetachReplicaMasterHost的同义词
  "MasterFailoverLostInstancesDowntimeMinutes": 0,  #在主故障转移(包括失败的主副本和丢失的副本)之后丢失的任何服务器停机的分钟数。0表示禁用
  "PostponeSlaveRecoveryOnLagMinutes": 0,  #PostponeReplicaRecoveryOnLagMinutes的同义词
  "OSCIgnoreHostnameFilters": [],  #OSC副本推荐将忽略与给定模式匹配的副本主机名
  "GraphiteAddr": "",
  "GraphitePath": "",
  "GraphiteConvertHostnameDotsToUnderscores": true,

  "RaftEnabled": true,   #raft模式
  "BackendDB": "mysql",  #后台数据库类型
  "RaftBind": "192.168.89.103",  #绑定之地,本机IP
  "RaftDataDir": "/var/lib/orchestrator",  #数据目录,如果不存在,则自动创建
  "DefaultRaftPort": 10008,  #raft通信端口,所有机器必须保持一致
  "RaftNodes": [   #raft节点,必须包含所有节点
    "192.168.89.100", 
    "192.168.89.102",
    "192.168.89.103"
    ],

  "ConsulAddress": "",  #找到Consul HTTP api的地址。示例:127.0.0.1:8500
  "ConsulAclToken": ""  #用于写入Consul KV的ACL令牌
}

三、启动:

1)在所有被管理的mysql实例上(本机为3307端口)建立管理账号:

GRANT ALL ON *.* TO 'failover'@'127.0.0.1' IDENTIFIED BY '123456'; 

GRANT ALL ON *.* TO 'failover'@'192.168.89.%' IDENTIFIED BY '123456'; 

在所有orchestrator实例的mysql上建立管理账号:

GRANT ALL ON *.* TO 'root'@'127.0.0.1' IDENTIFIED BY '123456'; 

2)创建复制拓补环境,这里不细说,把三台主机创建成复制结构即可。

3)编辑hosts文件,写入三台的hostname。

4)启动orchestrator:

        nohup orchestrator http &      orchestrator会自动到/usr/local/orchestrator下查找到配置文件

5)打开web界面:IP:3000。orchestrator会自动发现复制拓补结构并显示到界面上,如果没有发现,则可以手动发现。

orchestrator-client -c discover -i 实例:端口

orchestrator可以很好地与proxysql中间件结合,做读写分离与高可用。事实上,percona官方也推荐这套组合,mysqlfailover+proxysql也是很好的一套,不过MySQLfailover需要自己定制脚本。

关于hook或者其他生态工具,可以看我开源的二次开发的orchestrator地址: Orchestrator
也欢迎一起交流,可以私信我加我微信一起交流
原创文章,转载请注明哟


http://chatgpt.dhexx.cn/article/3ENbGFVY.shtml

相关文章

GitHub 源代码疑遭泄漏

聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 TypeScript的开发者Resynth 发布题为《GitHub 源代码泄漏》的文章指出,GitHub.com 的所有源代码被公开。 (泄漏者在 Readme 中指出,文档包括日…

2020 最好的Linux网络监控工具

前言 虽然这个清单包含开源的和闭源的产品,但它着重于介绍基于 Linux 的网络监控工具, 少数常用工具只能在 Windows,Pandora 或其他系统上运行,但是大多数网络监视工具都在Linux系统上运行,因为 Linux 通常是 IT 专家的…

网络地址转换(NAT)技术是否拖慢了互联网的发展?(2020 修订版)

2020 年修订版前言:看到有人还是对 IPv4 和 IPv6 的关系搞不清楚,好像只要有了 IPv6 就可以不要 IPv4 了,我只好把老文章祭出来了,当时也是我们接触 IPv6 的开始,两年下来,有些地方做了一些修订。 --- 正文…

Nat. Mach. Intell. | 人工智能的透明度和可重复性

今天给大家介绍多伦多大学的研究人员发表在nature machine intelligence上的一篇文章。文章指出McKinney等人利用AI在乳腺癌筛选上的工作,缺乏研究方法和代码实现的细节,阻碍了透明且可重复(transparent and reproducible)的AI研究…

网络安全学习中的工具

1> Nmap Nmap,也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包。 系统管理员可以利用nmap来探测工作环境中未经批准使用的服务器,但是黑客会利用nmap来搜集目标电脑的网络设定,从而计划攻击的方法。 其基本功能有三…

p2p网络测试工具_(官方更新)IPFS的网络层——libp2p在2020的发展

如果您在分散的点对点空间中执行任何操作,您可能听说过 libp2p - 用于对等应用程序的模块化网络堆栈。 libp2p 由许多模块化库组成,p2p 网络开发人员可以从中选择和重用所需的协议,同时便于应用程序之间的升级和互操作。这有助于 Web3 开发人…

NAT会话穿越应用程序(STUN)(RFC-5389)

RFC文档链接 摘要 NAT会话穿越应用程序 (STUN) 是一种协议,在处理网络地址转换(Network Address Translator, NAT)穿越时充当其他协议的工具。终端可以使用它来确定NAT分配给它的IP地址和端口。它还可以用来检查两端之间的连通性,并作为keep-alive协议…

教你用 CSS 实现超真实的 3D 相册,让你的照片立体感 UPUP

前言 现如今网页越来越趋近于动画,相信大家平时浏览网页或多或少都能看到一些动画效果,今天我们来做一个有意思的动画效果,通过 css3 实现 3d 效果的立方体相册,下面一起看看吧。 实现思路 首先我们要确定好 html 的结构以及要使…

HTML+CSS实现3D立体相册

程序员的浪漫&#xff0c;话不多说上代码。 HTML: <body><div id"cube"><!--外层盒子--><ul><li><img src"./imgs/1.jpg" ></li><li><img src"./imgs/2.jpg" ></li><li>&l…

该换壁纸啦,记录一个用CSS和HTML做的3D立体相册

这几天看东宫沉迷于陈星旭&#xff0c;李承鄞太绝了&#xff01;这不得把壁纸安排上&#xff1f;简单记录一下制作过程。 1、准备照片 需要1张大的背景图和6张3d相册用图存放在img文件夹中。 可以先使用PS、美图秀秀或者其他修图软件等将相册用图改成200px*200px。 注意文件…

抖音程序员HTML相册,快手抖音程序员表白女朋友3D立体相册源码html网页相册代码...

前几天分享了一套源码&#xff0c;今天又为大家带来一套类似的源码&#xff0c;希望大家喜欢! 快手抖音很火的程序员女朋友3D立体相册源码html网页相册代码&#xff0c;经测试在IE8浏览器下无法预览&#xff0c;建议使用支持HTML5与css3效果较好的360浏览器预览本源码。 代码如…

H5 3d立体相册 CSS3特性

CSS3 变形特性,立方相册,3d旋转 之前看见过3d效果的立体相册,挺羡慕的,现在自己也有机会实现属于自己的3d立体相册了~~~话不多说,开搞… 一, 准备材料 六张自己喜欢的图片,六个面,怎么简单方便怎么来,名字直接取123456,后缀.jpg,放到img文件夹下一张小图片,大点也不要紧,为了浏…

js制作3d立体旋转相册

使用js做一个3d立体旋转相册 可自由拖拽 源码如下 <!DOCTYPE html> <html> <head> <meta charset"utf-8"><title>1</title><style type"text/css">.main{perspective: 800px;}#mian img{width: 200px;height:…

3D立体动态相册(带背景音乐)HTML+CSS脚本

3D立体动态相册&#xff08;带背景音乐&#xff09;HTMLCSS脚本。程序员硬核送礼方式。。。 动画效果 截图效果&#xff1a; 照片准备&#xff1a; 命名为1、2、3、…… 音乐&#xff1a; 将文件依次放在各自文件夹中&#xff1a; CSS文本&#xff0c;命名&#xff1a;index.…

抖音3d相册html代码,抖音3D立体相册表白代码.doc

抖音3D立体相册表白浪漫代码 首先先建立html文件css-3d旋转 之后再新建一个CSS的文件夹 并在css文件夹中建立txt文件&#xff0c;并且把代码复制进去&#xff0c;修改后缀名为.css html{ background: #000; height: 100%; } /*最外层容器样式*/ .wrap{ position: relative; pos…

打造3D立体相册

项目目录结构&#xff1a; HTML代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><link type"text/css" rel"styleSheet" href"css/wrap.css" /><…

MATLAB竟也能制作3D相册?教你用MATLAB制作立体动态相册

效果 教程部分 1 图片导入与大小重设 需要有一个名为album的文件夹和当前m文件在同一文件夹&#xff0c;另外ablum文件夹内至少要有一张jpg格式图片 path.\album\;%文件夹名称 filesdir(fullfile(path,*.jpg)); picNumsize(files,1);%遍历路径下每一幅图像 for i1:picNumfi…

HTML 3d立体旋转相册

效果&#xff1a;&#xff08;实际是动态旋转&#xff09; 目录&#xff1a;&#xff08;根据自己需要替换图片就行了 大照片是400*400 小照片是100*100&#xff09; 提取码&#xff1a;1122 代码链接 index.html <!DOCTYPE html> <html lang"en"> <…

3D立体相册不过是冷锋蓝plus版 html+css

一.话不多&#xff0c;先看效果&#xff1a; 转念一想&#xff0c;好像很久很久没出css特效的文章了&#xff0c;特别是工作之后&#xff0c;更少了。偶然翻看电脑内存的时候&#xff0c;发现这个自己1年多以前写的特效&#xff0c;甚美&#xff0c;又勾起我一段尘封的回忆。。…

创意相册、3D立体相册

3D表白相册 精美的3D动态相册&#xff0c;快去做给她吧&#xff01; 点我下载 换的图片格式要一样&#xff0c;实在不一样就去代码里面改后缀名 https://download.csdn.net/download/weixin_43474701/60386577