热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

centos7mogodb-3.4.4dockerfile

下载wgethttps:fastdl.mongodb.orglinuxmongodb-linux-x86_64-rhel70-3.4.4.tgz本地dockerfil

下载

 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.4.4.tgz


本地dockerfile

[root@yzb-centos72-3 software]# more dockerfile/mongodb

FROM centos
MAINTAINER jiangleid@163.com
RUN mkdir -p /home/software
WORKDIR /home/software
RUN yum install -y unzip zip;
RUN yum install -y net-tools

# '***** mongodb ******'
ADD mongodb-linux-x86_64-rhel70-3.4.4.tgz /usr/local/
RUN mv /usr/local/mongodb-linux-x86_64-rhel70-3.4.4 /usr/local/mongodb-3.4.4
ADD mongodb/ /usr/local/mongodb-3.4.4/conf/
RUN chmod -R 755 /usr/local/mongodb-3.4.4

本地mongodb 目录结构

[root@yzb-centos72-3 mongodb]# tree
.
├── config
│   ├── config_21000.conf
│   ├── db
│   └── log
├── mongos
│   ├── log
│   └── mongos_20000.conf
└── shard
    ├── shard1
    │   ├── db
    │   ├── log
    │   └── shard1_22001.conf
    ├── shard2
    │   ├── db
    │   ├── log
    │   └── shard2_22002.conf
    └── shard3
        ├── db
        ├── log
        └── shard3_22003.conf

15 directories, 5 files

基于dockerfile 构建影像

[root@yzb-centos72-3 software]# docker build -t mongodb:v1.0 -f dockerfile/mongodb .

Sending build context to Docker daemon 300.8 MB
Step 1 : FROM centos
 ---> a8493f5f50ff
Step 2 : MAINTAINER jiangleid@yonyou.com
 ---> Using cache
 ---> 44af6950f23e
Step 3 : RUN mkdir -p /home/software
 ---> Using cache
 ---> 5778393e7b40
Step 4 : WORKDIR /home/software
 ---> Using cache
 ---> ebdc5e58fd29
、、、、、、、、、
、、、、、、、、、
Step 10 : RUN chmod -R 755 /usr/local/mongodb-3.4.4
 ---> Running in 412af413e692
 ---> ede0c75edfac
Removing intermediate container 412af413e692
Successfully built ede0c75edfac
查看新建立的影像, 可以看到 iamge id: ede0c75edfac

[root@yzb-centos72-3 software]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mongodb             v1.0                ede0c75edfac        2 minutes ago       1.183 GB
mariadb             v1.0                5f1a79c3025b        19 hours ago        431.3 MB
nginx               v1.0                896a46fdd902        22 hours ago        1.07 GB
docker.io/centos    latest              a8493f5f50ff        5 weeks ago         192.5 MB
docker.io/centos    7.3.1611            67591570dd29        5 months ago        191.8 MB

启动镜像

[root@yzb-centos72-3 software]# docker run -it -p 20000:20000 -p 21000:21000 -p 22001:22001 -p 22002:22002 -p 22003:22003 ede0c75edfac
[root@db5e67a0513a software]#

容器内的mongodb

[root@a24970088f14 mongodb-3.4.4]# ll
total 120
-rwxr-xr-x 1 root root 34520 Apr 20 22:20 GNU-AGPL-3.0
-rwxr-xr-x 1 root root 16726 Apr 20 22:20 MPL-2
-rwxr-xr-x 1 root root  1359 Apr 20 22:20 README
-rwxr-xr-x 1 root root 55625 Apr 20 22:20 THIRD-PARTY-NOTICES
drwxr-xr-x 2 root root  4096 May 18 00:52 bin
drwxr-xr-x 5 root root    44 May 18 00:52 conf

启动mongodb的 config  shard  mongos

进入bin目录

启动config

[root@a24970088f14 bin]# ./mongod -f ../conf/config/config_21000.conf
about to fork child process, waiting until server is ready for connections.
forked process: 35
child process started successfully, parent exiting

config_21000.conf 文件内容

[root@a24970088f14 bin]# more  ../conf/config/config_21000.conf
replSet=cfgReplSet
cOnfigsvr=true
port=21000
dbpath=/usr/local/mongodb-3.4.4/conf/config/db
logpath=/usr/local/mongodb-3.4.4/conf/config/log/config.log
fork=true
登入config,配置 config副本集

[root@db5e67a0513a bin]# ./mongo --port 21000
MongoDB shell version v3.4.4
connecting to: mongodb://127.0.0.1:21000/
MongoDB server version: 3.4.4
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        http://docs.mongodb.org/
Questions? Try the support group
        http://groups.google.com/group/mongodb-user
Server has startup warnings:
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten]
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten]
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten]
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten]
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-05-18T01:23:15.669+0000 I CONTROL  [initandlisten]

配置:

> rs.initiate({_id:"cfgReplSet", configsvr:true, members:[{_id:0, host:"172.20.4.132:21000"}]})
{ "ok" : 1 }

查看配置

cfgReplSet:SECONDARY> rs.status()
{
        "set" : "cfgReplSet",
        "date" : ISODate("2017-05-18T01:26:22.490Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "configsvr" : true,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1495070775, 10),
                        "t" : NumberLong(1)
                },
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1495070775, 10),
                        "t" : NumberLong(1)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1495070775, 10),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1495070775, 10),
                        "t" : NumberLong(1)
                }
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "172.20.4.132:21000",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 187,
                        "optime" : {
                                "ts" : Timestamp(1495070775, 10),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2017-05-18T01:26:15Z"),
                        "infoMessage" : "could not find member to sync from",
                        "electionTime" : Timestamp(1495070772, 1),
                        "electionDate" : ISODate("2017-05-18T01:26:12Z"),
                        "configVersion" : 1,
                        "self" : true
                }
        ],
        "ok" : 1
}

因为我这测试,只有一个config,若是多个的话,在members 数组中配置上即可。

如:

rs.initiate({_id:"cfgReplSet", configsvr:true, members:[{_id:0, host:"172.20.4.132:21000"},{_id:0, host:"172.20.4.133:21000"}{_id:0, host:"172.20.4.134:21000"}]})

也可以用add的方式追加,如后续新加入的副本

rs.add("172.20.4.133:21000")  # 添加备份库

rs.addArb("172.20.4.134:21000")#添加仲裁

exit 退出


启动shard1

[root@db5e67a0513a bin]# ./mongod -f ../conf/shard/shard1/shard1_22001.conf
about to fork child process, waiting until server is ready for connections.
forked process: 108
child process started successfully, parent exiting

文件shard1_22001.conf

bye
[root@db5e67a0513a bin]# more ../conf/shard/shard1/shard1_22001.conf
#分片服务
shardsvr=true
#副本名称
replSet=shard1ReplSet
#端口
port=22001
# 数据库文件位置
dbpath=/usr/local/mongodb-3.4.4/conf/shard/shard1/db
# 日志文件位置
logpath=/usr/local/mongodb-3.4.4/conf/shard/shard1/log/log
# 是否以守护进程方式运行
fork=true
# 以追加方式写入日志
logappend=true
# 开启用户认证
#auth = true


启动shard2

[root@db5e67a0513a bin]# ./mongod -f ../conf/shard/shard2/shard2_22002.conf
about to fork child process, waiting until server is ready for connections.
forked process: 139
child process started successfully, parent exiting

文件shard2_22002.conf

[root@db5e67a0513a bin]# more  ../conf/shard/shard2/shard2_22002.conf   
#分片服务
shardsvr=true
#副本名称
replSet=shard2ReplSet
#端口
port=22002
# 数据库文件位置
dbpath=/usr/local/mongodb-3.4.4/conf/shard/shard2/db
# 日志文件位置
logpath=/usr/local/mongodb-3.4.4/conf/shard/shard2/log/log
# 是否以守护进程方式运行
fork=true
# 以追加方式写入日志
logappend=true
# 开启用户认证
#auth = true


启动shard3

[root@db5e67a0513a bin]# ./mongod -f ../conf/shard/shard3/shard3_22003.conf
about to fork child process, waiting until server is ready for connections.
forked process: 170
child process started successfully, parent exiting

文件shard3_22003.conf

[root@db5e67a0513a bin]# more ../conf/shard/shard3/shard3_22003.conf 
#分片服务
shardsvr=true
#副本名称
replSet=shard3ReplSet
#端口
port=22003
# 数据库文件位置
dbpath=/usr/local/mongodb-3.4.4/conf/shard/shard3/db
# 日志文件位置
logpath=/usr/local/mongodb-3.4.4/conf/shard/shard3/log/log
# 是否以守护进程方式运行
fork=true
# 以追加方式写入日志
logappend=true
# 开启用户认证
#auth = true


登入配置shard1、shard2、shard3的副本集

[root@db5e67a0513a bin]# ./mongo --port 22001
MongoDB shell version v3.4.4
connecting to: mongodb://127.0.0.1:22001/
MongoDB server version: 3.4.4
Server has startup warnings:
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten]
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten]
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten]
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-05-18T01:30:37.013+0000 I CONTROL  [initandlisten]
2017-05-18T01:30:37.014+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-05-18T01:30:37.014+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-05-18T01:30:37.014+0000 I CONTROL  [initandlisten]
> rs.initiate({_id:"shard1ReplSet", members:[{ _id:0, host:"172.20.4.132:22001" }] })
{ "ok" : 1 }
shard1ReplSet:SECONDARY> rs.status();
{
        "set" : "shard1ReplSet",
        "date" : ISODate("2017-05-18T01:40:10.006Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1495071605, 1),
                        "t" : NumberLong(1)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1495071605, 1),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1495071605, 1),
                        "t" : NumberLong(1)
                }
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "172.20.4.132:22001",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 574,
                        "optime" : {
                                "ts" : Timestamp(1495071605, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2017-05-18T01:40:05Z"),
                        "infoMessage" : "could not find member to sync from",
                        "electionTime" : Timestamp(1495071603, 2),
                        "electionDate" : ISODate("2017-05-18T01:40:03Z"),
                        "configVersion" : 1,
                        "self" : true
                }
        ],
        "ok" : 1
}
shard1ReplSet:PRIMARY>

同样的方式登入 22002,22003配置shard2、shard3.

同上面的config一样,我这没有起副本,所有的副本集中都只是一个节点。

若是多个副本,也是按照config下面说的一样,在members的数组中添加上即可。


启动mongos

[root@db5e67a0513a bin]# ./mongos -f ../conf/mongos/mongos_20000.conf
2017-05-18T01:56:28.075+0000 W SHARDING [main] Running a sharded cluster with fewer than 3 config servers should only be done for testing purposes and is not recommended for production.
about to fork child process, waiting until server is ready for connections.
forked process: 357
child process started successfully, parent exiting

登入mongos

[root@db5e67a0513a bin]# ./mongo --port 20000

MongoDB shell version v3.4.4
connecting to: mongodb://127.0.0.1:20000/
MongoDB server version: 3.4.4
Server has startup warnings:
2017-05-18T01:56:28.090+0000 I CONTROL  [main]
2017-05-18T01:56:28.090+0000 I CONTROL  [main] ** WARNING: Access control is not enabled for the database.
2017-05-18T01:56:28.090+0000 I CONTROL  [main] **          Read and write access to data and configuration is unrestricted.
2017-05-18T01:56:28.090+0000 I CONTROL  [main] ** WARNING: You are running this process as the root user, which is not recommended.
2017-05-18T01:56:28.090+0000 I CONTROL  [main]
mongos>

新建 test db

mongos> use test

查看当前使用的db

mongos> db
test

为test db 添加用户  test  密码  111111

mongos> db.createUser({user:"test",pwd:"111111",roles:[{role:"readWrite",db:"test"}]})
Successfully added user: {
        "user" : "test",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "test"
                }
        ]
}

验证用户登录

mongos> db.auth("test","111111")
1

成功

这时插入数据会报错,因为db test没有配置shard

mongos> db.test.insert({"name":"mayun","age":"50"})
WriteResult({
        "writeError" : {
                "code" : 70,
                "errmsg" : "unable to target write op for collection test.test :: caused by :: ShardNotFound: Database test not found due to No shards found"
        }
})

为数据库配置shard

将之前的shard加入到mongos,以便路由

mongos> sh.addShard("shard1ReplSet/172.20.4.132:22001")
{ "shardAdded" : "shard1ReplSet", "ok" : 1 }

mongos> sh.addShard("shard2ReplSet/172.20.4.132:22002")
{ "shardAdded" : "shard2ReplSet", "ok" : 1 }
mongos> sh.addShard("shard3ReplSet/172.20.4.132:22003")
{ "shardAdded" : "shard3ReplSet", "ok" : 1 }

这里添加的副本集,只需要是副本集名加上一个副本集中的成员即可,不一定要是primary节点。

设置 库 集合(表)的分片

mongos> sh.enableSharding("test")
{ "ok" : 1 }
mongos> sh.shardCollection("test.user",{"_id":"hashed"})
{ "collectionsharded" : "test.user", "ok" : 1 }

插入、查询数据

mongos> db
test
mongos> db.user.insert({"name":"mayun","age":"50"})
WriteResult({ "nInserted" : 1 })
mongos> db.user.insert({"name":"wangjinlin","age":"55"})
WriteResult({ "nInserted" : 1 })

mongos> db.user.insert({"name":"bill","age":"20"})
WriteResult({ "nInserted" : 1 })

mongos> db.user.insert({"name":"bill1","age":"201"})
WriteResult({ "nInserted" : 1 })
mongos> db.user.insert({"name":"bill2","age":"202"})
WriteResult({ "nInserted" : 1 })

mongos> db.user.insert({"name":"bill3","age":"203"})
WriteResult({ "nInserted" : 1 })
mongos> db.user.insert({"name":"bill4","age":"204"})
WriteResult({ "nInserted" : 1 })

mongos> db.user.find();
{ "_id" : ObjectId("591d084bbe63f26c975b510e"), "name" : "wangjinlin", "age" : "55" }
{ "_id" : ObjectId("591d0f51abc9d23287a29044"), "name" : "bill", "age" : "20" }
{ "_id" : ObjectId("591d0f6cabc9d23287a29047"), "name" : "bill3", "age" : "203" }
{ "_id" : ObjectId("591d0f5cabc9d23287a29045"), "name" : "bill1", "age" : "201" }
{ "_id" : ObjectId("591d0f64abc9d23287a29046"), "name" : "bill2", "age" : "202" }
{ "_id" : ObjectId("591d0823be63f26c975b510d"), "name" : "mayun", "age" : "50" }
{ "_id" : ObjectId("591d0f74abc9d23287a29048"), "name" : "bill4", "age" : "204" }


查看分片状态

mongos> db.user.stats();

{
        "sharded" : true,
        "capped" : false,
        "ns" : "test.user",
        "count" : 7,
        "size" : 358,
        "storageSize" : 81920,
        "totalIndexSize" : 163840,
        "indexSizes" : {
                "_id_" : 81920,
                "_id_hashed" : 81920
        },
        "avgObjSize" : 50.714285714285715,
        "nindexes" : 2,
        "nchunks" : 6,
        "shards" : {
                "shard1ReplSet" : {
                        "ns" : "test.user",
                        "size" : 155,
                        "count" : 3,
                        "avgObjSize" : 51,
                        "storageSize" : 32768,
                        "capped" : false,
                        "wiredTiger" : {

、、、、、、、、

、、、、、、

  "shard2ReplSet" : {
                        "ns" : "test.user",
                        "size" : 102,
                        "count" : 2,
                        "avgObjSize" : 51,
                        "storageSize" : 16384,
                        "capped" : false,
                        "wiredTiger" : {
                                "metadata" : {
                                        "formatVersion" : 1
                                },

、、、、、、、、

、、、、、、、、

"shard3ReplSet" : {
                        "ns" : "test.user",
                        "size" : 101,
                        "count" : 2,
                        "avgObjSize" : 50,
                        "storageSize" : 32768,
                        "capped" : false,
                        "wiredTiger" : {
                                "metadata" : {
                                        "formatVersion" : 1
                                },

可以看到user总记录是7

shard1ReplSet:3, shard2ReplSet:2, shard3ReplSet:2


结束


推荐阅读
  • 在Kubernetes上部署JupyterHub的步骤和实验依赖
    本文介绍了在Kubernetes上部署JupyterHub的步骤和实验所需的依赖,包括安装Docker和K8s,使用kubeadm进行安装,以及更新下载的镜像等。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • OpenCV4.5.0+contrib编译流程及解决错误方法
    本文介绍了OpenCV4.5.0+contrib的编译流程,并提供了解决常见错误的方法,包括下载失败和路径修改等。同时提供了相关参考链接。 ... [详细]
  • 判断编码是否可立即解码的程序及电话号码一致性判断程序
    本文介绍了两个编程题目,一个是判断编码是否可立即解码的程序,另一个是判断电话号码一致性的程序。对于第一个题目,给出一组二进制编码,判断是否存在一个编码是另一个编码的前缀,如果不存在则称为可立即解码的编码。对于第二个题目,给出一些电话号码,判断是否存在一个号码是另一个号码的前缀,如果不存在则说明这些号码是一致的。两个题目的解法类似,都使用了树的数据结构来实现。 ... [详细]
  • 查找给定字符串的所有不同回文子字符串原文:https://www ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • phpcomposer 那个中文镜像是不是凉了 ... [详细]
  • 本文介绍了200个经典c语言源代码,包括函数的使用,如sqrt函数、clanguagefunct等。这些源代码可以帮助读者更好地理解c语言的编程方法,并提供了实际应用的示例。 ... [详细]
  • 文章目录题目:二叉搜索树中的两个节点被错误地交换。基本思想1:中序遍历题目:二叉搜索树中的两个节点被错误地交换。请在不改变其结构的情况下 ... [详细]
  • Python15行代码实现免费发送手机短信,推送消息「建议收藏」
    Python15行代码实现免费发 ... [详细]
  • 在搜索数据库中的数据时,您可以使用SQL通配符。SQL通配符在搜索数据库中的数据时,SQL通配符可以替代一个或多个字符。SQL通配符必须与LIKE运算符 ... [详细]
  • Flutter 布局(四) Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth详解
    本文主要介绍Flutter布局中的Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth四种控件,详细介绍了其布局 ... [详细]
author-avatar
Yatmiiml
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有