Docker微服务部署
接下来进入网络的实战内容,分别部署下redis集群和springboot服务。
Redis集群实战部署
下面部署如图所示的三主三从的Redis集群,其实质就是启动六个容器,并将他们连接到同一自定义网络上
1 创建自定义网络
首先创建网络名为redis-tml的自定义网络:docker network create redis-tml --subnet 172.38.0.0/16
[root@192 ~]# docker network create redis-tml --subnet 172.38.0.0/16 80fcee363b04bdb8f2d6296fe4b5863d83900edfc42ff7fdf28c581b8b843ee9 [root@192 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 173795075c5b bridge bridge local fcddcee8a2d1 host host local a2b305685ea4 mynet bridge local 9efbda880fae none null local 80fcee363b04 redis-tml bridge local [root@192 ~]# docker inspect redis-tml [ { "Name": "redis-tml", "Id": "80fcee363b04bdb8f2d6296fe4b5863d83900edfc42ff7fdf28c581b8b843ee9", "Created": "2022-03-06T11:20:45.767528371+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.38.0.0/16" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] [root@192 ~]#
2 编写容器所需的redis配置文件
通过以下脚本创建六个Redis 的配置信息:
for port in $(seq 1 6); \ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat << EOF >/mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done
创建节点并进入查看节点配置信息:
[root@192 ~]# for port in $(seq 1 6); \ > do \ > mkdir -p /mydata/redis/node-${port}/conf > touch /mydata/redis/node-${port}/conf/redis.conf > cat << EOF >/mydata/redis/node-${port}/conf/redis.conf > port 6379 > bind 0.0.0.0 > cluster-enabled yes > cluster-config-file nodes.conf > cluster-node-timeout 5000 > cluster-announce-ip 172.38.0.1${port} > cluster-announce-port 6379 > cluster-announce-bus-port 16379 > appendonly yes > EOF > done [root@192 ~]# cd /mydata/redis [root@192 redis]# ls node-1 node-2 node-3 node-4 node-5 node-6 [root@192 redis]# cd node-1 [root@192 node-1]# ls conf [root@192 node-1]# cd conf [root@192 conf]# ls redis.conf [root@192 conf]# cat redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.11 cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes [root@192 conf]#
3 启动所有容器并设置挂载目录
接下来启动容器并设置容器挂载目录:
for port in $(seq 1 6); \ do docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-tml-${port} \ -v /mydata/redis/node-${port}/data:/data \ -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis-tml --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \ done
执行容器创建命令并查看结果:
[root@192 /]# for port in $(seq 1 6); \ > do > docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-tml-${port} \ > -v /mydata/redis/node-${port}/data:/data \ > -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \ > -d --net redis-tml --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \ > done 4e2fbf58e42a91c9da043358a60dfe96c67d758d6bd92d0058e797bb0fe64891 21817e4511e25c2df2e8c461e3b287d092049f04bb6580ceb5c0ffcaa2ff638b a70476765adf8e9f4bb544ddaf3ce5aa8519f15056a46be8cbb48dbe025c0e9a 497dc6d028a4d03df7184f2f99e619c071ee38f5ed3ccc697cf406ea020f17db e61d6e975db74423253f2f9abcbeb34a4383439cbff7a55120692136dfa3c87a c81b1d29ea56a79d251c337d3cd6b6d4564a5935ac1ecc2d1389475fe91d1c8f [root@192 /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c81b1d29ea56 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 10 seconds ago Up 3 seconds 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-tml-6 e61d6e975db7 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 11 seconds ago Up 9 seconds 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-tml-5 497dc6d028a4 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 13 seconds ago Up 10 seconds 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-tml-4 a70476765adf redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 14 seconds ago Up 12 seconds 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp redis-tml-3 21817e4511e2 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 20 seconds ago Up 13 seconds 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-tml-2 4e2fbf58e42a redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 21 seconds ago Up 19 seconds 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-tml-1 650925c833ed tomcat:8.0 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:49158->8080/tcp, :::49158->8080/tcp tomcat-tml-net-02 b9e24d2619cb tomcat:8.0 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:49157->8080/tcp, :::49157->8080/tcp tomcat-tml-net-01 3e862598e630 tomcat:8.0 "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:49156->8080/tcp, :::49156->8080/tcp tomcat02 6cd417097796 tomcat:8.0 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:49155->8080/tcp, :::49155->8080/tcp tomcat01 50b626fc91d2 tianmaolin/tml-mydockerfile-tomcat:1.0 "/bin/sh -c '/usr/lo…" 13 hours ago Up 13 hours 0.0.0.0:49154->8080/tcp, :::49154->8080/tcp tomcat-tml [root@192 /]#
4 构建Redis容器集群
下面进入到redis-tml-1容器中创建集群redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
,使用该命令构建集群:
[root@192 ~]# docker exec -it redis-tml-1 /bin/sh /data # pwd /data # ls appendonly.aof nodes.conf /data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1 >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 172.38.0.15:6379 to 172.38.0.11:6379 Adding replica 172.38.0.16:6379 to 172.38.0.12:6379 Adding replica 172.38.0.14:6379 to 172.38.0.13:6379 M: b1fc3e1075f55e7e7d0fb6051afbacbe5e5aaead 172.38.0.11:6379 slots:[0-5460] (5461 slots) master M: 3726bd8feb6f538db1299121f1b99e1fe06db0b0 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master M: 69f5719cfe395e4a28874840560a2064b14d7468 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master S: 07f17e5e4dc68d988d12ab42754ebb13bea28969 172.38.0.14:6379 replicates 69f5719cfe395e4a28874840560a2064b14d7468 S: d47804444b5abe6a8e8d9f2637be06d37f7a6cd5 172.38.0.15:6379 replicates b1fc3e1075f55e7e7d0fb6051afbacbe5e5aaead S: dbd9154bd598b6af1ece5e3b567c04b96989f93c 172.38.0.16:6379 replicates 3726bd8feb6f538db1299121f1b99e1fe06db0b0 Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ... >>> Performing Cluster Check (using node 172.38.0.11:6379) M: b1fc3e1075f55e7e7d0fb6051afbacbe5e5aaead 172.38.0.11:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: 3726bd8feb6f538db1299121f1b99e1fe06db0b0 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 07f17e5e4dc68d988d12ab42754ebb13bea28969 172.38.0.14:6379 slots: (0 slots) slave replicates 69f5719cfe395e4a28874840560a2064b14d7468 S: dbd9154bd598b6af1ece5e3b567c04b96989f93c 172.38.0.16:6379 slots: (0 slots) slave replicates 3726bd8feb6f538db1299121f1b99e1fe06db0b0 S: d47804444b5abe6a8e8d9f2637be06d37f7a6cd5 172.38.0.15:6379 slots: (0 slots) slave replicates b1fc3e1075f55e7e7d0fb6051afbacbe5e5aaead M: 69f5719cfe395e4a28874840560a2064b14d7468 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. /data #
查看集群信息:
/data # redis-cli -c 127.0.0.1:6379> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:164 cluster_stats_messages_pong_sent:157 cluster_stats_messages_sent:321 cluster_stats_messages_ping_received:152 cluster_stats_messages_pong_received:164 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:321 127.0.0.1:6379>
查看节点信息cluster nodes
,可以清楚的看到Redis节点的主从关系。
127.0.0.1:6379> cluster nodes 3726bd8feb6f538db1299121f1b99e1fe06db0b0 172.38.0.12:6379@16379 master - 0 1646540001511 2 connected 5461-10922 07f17e5e4dc68d988d12ab42754ebb13bea28969 172.38.0.14:6379@16379 slave 69f5719cfe395e4a28874840560a2064b14d7468 0 1646540000503 4 connected dbd9154bd598b6af1ece5e3b567c04b96989f93c 172.38.0.16:6379@16379 slave 3726bd8feb6f538db1299121f1b99e1fe06db0b0 0 1646540001000 6 connected d47804444b5abe6a8e8d9f2637be06d37f7a6cd5 172.38.0.15:6379@16379 slave b1fc3e1075f55e7e7d0fb6051afbacbe5e5aaead 0 1646540001000 5 connected 69f5719cfe395e4a28874840560a2064b14d7468 172.38.0.13:6379@16379 master - 0 1646540001511 3 connected 10923-16383 b1fc3e1075f55e7e7d0fb6051afbacbe5e5aaead 172.38.0.11:6379@16379 myself,master - 0 1646539999000 1 connected 0-5460 127.0.0.1:6379>
5 测试集群功能
测试主从复制是否生效,设置一个key,然后获取一下这个key
/data # redis-cli -c 172.38.0.15:6379> set ttt shuai -> Redirected to slot [15942] located at 172.38.0.13:6379 OK 172.38.0.13:6379> get ttt "shuai" 172.38.0.13:6379>
可以看到:172.38.0.13
存了这个key,对应的容器是redis-tml-3:新建一个会话,停止redis-tml-3容器服务,
[root@192 ~]# docker stop redis-tml-3 redis-tml-3 [root@192 ~]#
此时重新连接Redis-cli客户端,再次获取ttt
,重定向到了redis-tml-3节点的从节点redis-tml-4中处理
/data # redis-cli -c 127.0.0.1:6379> get ttt -> Redirected to slot [15942] located at 172.38.0.14:6379 "shuai" 172.38.0.14:6379>
再次查看节点信息,可以看到13master的redis服务down了,14的当选为新的master:
172.38.0.14:6379> cluster nodes dbd9154bd598b6af1ece5e3b567c04b96989f93c 172.38.0.16:6379@16379 slave 3726bd8feb6f538db1299121f1b99e1fe06db0b0 0 1646540807043 6 connected 07f17e5e4dc68d988d12ab42754ebb13bea28969 172.38.0.14:6379@16379 myself,master - 0 1646540806000 8 connected 10923-16383 3726bd8feb6f538db1299121f1b99e1fe06db0b0 172.38.0.12:6379@16379 master - 0 1646540809055 2 connected 5461-10922 69f5719cfe395e4a28874840560a2064b14d7468 172.38.0.13:6379@16379 master,fail - 1646540720260 1646540719000 3 connected b1fc3e1075f55e7e7d0fb6051afbacbe5e5aaead 172.38.0.11:6379@16379 slave d47804444b5abe6a8e8d9f2637be06d37f7a6cd5 0 1646540808000 7 connected d47804444b5abe6a8e8d9f2637be06d37f7a6cd5 172.38.0.15:6379@16379 master - 0 1646540808047 7 connected 0-5460 172.38.0.14:6379>
SpirngBoot项目打包部署
SpringBoot项目打包镜像分为以下五个步骤
1 构建SpringBoot项目
在idea中构建一个最简单的Spring Boot项目,写一个接口,启动项目本地测试能否正常调用。
内容如下:
package com.example.dockerspringboottest.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author tianmaolin * @since 2022-03-06 12:40:31 */ @RestController public class DockerController { @GetMapping("/hello-docker") public String hello(){ return "我是通过docker容器启动的springboot项目"; } }
本地测试如下:
2 打包springboot项目
使用Maven的package打包Spring Boot项目,生成jar包:
打包完成可以在输出目录找到jar包:
3 编写Dockerfile镜像文件
在idea编写一个Dockerfile镜像文件
文件内容如下:
FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
4 将Dockerfile与jar包发布到宿主机
将打包生成的jar包和编写的Dockerfile文件发送到服务器(在这里也就是虚拟机TML-2)上,这里我通过appNode处理:
5 在宿主机中构建镜像
接下来我们直接构建镜像即可:
[root@192 ~]# cd /home [root@192 home]# ls idea tml-1 [root@192 home]# cd idea [root@192 idea]# ls Dockerfile docker-springboot-test-0.0.1-SNAPSHOT.jar [root@192 idea]# docker build -f Dockerfile -t tml-docker-idea-springboot . Sending build context to Docker daemon 17.56MB Step 1/5 : FROM java:8 8: Pulling from library/java 5040bd298390: Pull complete fce5728aad85: Pull complete 76610ec20bf5: Pull complete 60170fec2151: Pull complete e98f73de8f0d: Pull complete 11f7af24ed9c: Pull complete 49e2d6393f32: Pull complete bb9cdec9c7f3: Pull complete Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d Status: Downloaded newer image for java:8 ---> d23bdf5b1b1b Step 2/5 : COPY *.jar /app.jar ---> 4e40af50856c Step 3/5 : CMD ["--server.port=8080"] ---> Running in 547d61b06081 Removing intermediate container 547d61b06081 ---> ab4113f7fc6e Step 4/5 : EXPOSE 8080 ---> Running in 1dc2de8fbcce Removing intermediate container 1dc2de8fbcce ---> 5f464a63a577 Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"] ---> Running in c0d55c04b170 Removing intermediate container c0d55c04b170 ---> 60803e8e55e4 Successfully built 60803e8e55e4 Successfully tagged tml-docker-idea-springboot:latest [root@192 idea]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c81b1d29ea56 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-tml-6 e61d6e975db7 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-tml-5 497dc6d028a4 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-tml-4 21817e4511e2 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-tml-2 4e2fbf58e42a redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up 48 minutes 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-tml-1 650925c833ed tomcat:8.0 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:49158->8080/tcp, :::49158->8080/tcp tomcat-tml-net-02 b9e24d2619cb tomcat:8.0 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:49157->8080/tcp, :::49157->8080/tcp tomcat-tml-net-01 3e862598e630 tomcat:8.0 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:49156->8080/tcp, :::49156->8080/tcp tomcat02 6cd417097796 tomcat:8.0 "catalina.sh run" 3 hours ago Up 3 hours 0.0.0.0:49155->8080/tcp, :::49155->8080/tcp tomcat01 50b626fc91d2 tianmaolin/tml-mydockerfile-tomcat:1.0 "/bin/sh -c '/usr/lo…" 14 hours ago Up 14 hours 0.0.0.0:49154->8080/tcp, :::49154->8080/tcp tomcat-tml [root@192 idea]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tml-docker-idea-springboot latest 60803e8e55e4 17 seconds ago 661MB tianmaolin/tml-mydockerfile-tomcat 1.0 94dbe2d0cb91 6 days ago 799MB redis 5.0.9-alpine3.11 3661c84ee9d0 22 months ago 29.8MB tomcat 8.0 ef6a7c98d192 3 years ago 356MB java 8 d23bdf5b1b1b 5 years ago 643MB [root@192 idea]#
6 运行镜像启动容器
运行镜像启动容器查看:
[root@192 idea]# docker run -d -P tml-docker-idea-springboot 37a22cf636f20e025383bea3c73d16b023ed87480f8324e9397ac6fd2230823d [root@192 idea]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 37a22cf636f2 tml-docker-idea-springboot "java -jar /app.jar …" 3 seconds ago Up 1 second 0.0.0.0:49159->8080/tcp, :::49159->8080/tcp elegant_mendel c81b1d29ea56 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-tml-6 e61d6e975db7 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-tml-5 497dc6d028a4 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-tml-4 21817e4511e2 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-tml-2 4e2fbf58e42a redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up 51 minutes 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-tml-1 650925c833ed tomcat:8.0 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:49158->8080/tcp, :::49158->8080/tcp tomcat-tml-net-02 b9e24d2619cb tomcat:8.0 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:49157->8080/tcp, :::49157->8080/tcp tomcat-tml-net-01 3e862598e630 tomcat:8.0 "catalina.sh run" 2 hours ago Up 2 hours 0.0.0.0:49156->8080/tcp, :::49156->8080/tcp tomcat02 6cd417097796 tomcat:8.0 "catalina.sh run" 3 hours ago Up 3 hours 0.0.0.0:49155->8080/tcp, :::49155->8080/tcp tomcat01 50b626fc91d2 tianmaolin/tml-mydockerfile-tomcat:1.0 "/bin/sh -c '/usr/lo…" 14 hours ago Up 14 hours 0.0.0.0:49154->8080/tcp, :::49154->8080/tcp tomcat-tml [root@192 idea]#
7 请求测试查看结果
我们从页面上进行一下请求测试:
可以发现请求成功
总结一下
本篇Blog为Docker基础及原理部分的最终篇,未学docker之前以为docker会将一个项目所需环境都放到一个容器里,例如springboot、mysql等,开始学之后发现一个容器只放置一个中间件又奇怪这些容器是怎么组合起来工作的,今天学习了网络之后才了解docker是通过网络配置可以构建集群、支持容器之间的相互访问,所以说【确立观点-提出疑问-学习-解决疑问-确立新观点-提出新疑问-再学习】似乎是一个正常的学习链路,在不断打到重建中螺旋向上的加深对事物的认知。