今天打算使用docker-compose 部署下服务器,本来以为很快可以完成,但是竟然滑铁卢,mysql8.0容器可以正常启动,但是go项目文件却怎么也连不上mysql容器,以下是事故现场和配置文件.解决方案在步骤里。

docker-compose logs mysql部分:

go项目部分:

docker-compose 文件如下:

version: '3.5'
services:stargate:image: ubuntu:18.04restart: alwaysworking_dir: /stargatevolumes:- ./stargate:/stargateports:- 18080:8080command: ./stargate dev.yamlnetworks:bridge_net:ipv4_address: ${BRIDGE_SUBNET_PREFIX}.03mysql:image: mysql:8.0restart: alwaysvolumes:- mysql_data:/var/lib/mysqlports:- "13306:3306"environment:- MYSQL_USER= "root"- MYSQL_PASSWORD= "123456"- MYSQL_ROOT_PASSWORD= "123456"- MYSQL_DATABASE= "stargate"- MYSQL_ROOT_HOST= "%"networks:bridge_net:ipv4_address: ${BRIDGE_SUBNET_PREFIX}.02
volumes:mysql_data: {}
networks:bridge_net:external: truename: ${BRIDGE_NET}

go项目的配置文件dev.yaml如下:

name: "stargate"
mode: "debug"
port: 8080
version: "v0.0.1"
start_time: "2022-08-23"
machine_id: 1
OwnerEmail: "936135768@qq.com"
enableHttps: falselog:level: "info"
#  filename: "stargate.log"
#  max_size: 200
#  max_age: 30
#  max_backups: 7
mysql:host: mysqlport: 13306user: "root"password: "123456"dbname: "stargate"max_open_conns: 200max_idle_conns: 50
~
~
~

go项目初始化mysql的代码如下:

// Init 初始化MySQL连接
func Init(cfg *settings.MySQLConfig) (err error) {// "user:stargateword@tcp(host:port)/dbname"dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true&loc=Local", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.DB)db, err = gorm.Open(mysql.Open(dsn))if err != nil {logger.Lg.Error("mysql connect failed...", zap.Error(err))return}mysqldb, _ := db.DB() 全局禁用表名复数//mysqldb.SingularTable(true) // 如果设置为true,`User`的默认表名为`user`,使用`TableName`设置的表名不受影响mysqldb.SetMaxOpenConns(cfg.MaxOpenConns)mysqldb.SetMaxIdleConns(cfg.MaxIdleConns)logger.Lg.Info("Init mysql success...")InitSYS_DIC()logger.Lg.Info("Init SYS_DIC success...")return
}

创建网络的命令如下:

docker network create bridge_net --subnet 172.31.0.0/24

.env文件如下:

BRIDGE_SUBNET_PREFIX=172.31.0BRIDGE_NET=bridge_net

进入mysql容器查看用户和host,可以看到stargate库已经创建,host为%:

oot@ecs-51ff home]# docker exec -it home_mysql_1  mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.30 MySQL Community Server - GPLCopyright (c) 2000, 2022, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> show tables;
ERROR 1046 (3D000): No database selected
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| stargate           |
| sys                |
+--------------------+
5 rows in set (0.00 sec)mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> select user,host from user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| root             | %         |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)mysql>

本来也参考了一些文章,在compose文件的mysql配置里加入了这个,结果mysql容器也起不来了。。。。:

 command:# default-authentication-plugin=mysql_native_password   mysql5为mysql_native_password, 支持较好, mysql8为默认为caching_sha2_password, 部分旧软件不支持;# character-set-server=utf8mb4                          默认创建新数据的新建字符集# collation-server=utf8mb4_general_ci                   默认创建新数据的新建排序规则# default-time-zone='+8:00'                             选择正8区# max_connections=1000                                  设置最大连接数# innodb_lock_wait_timeout=500                          innodb的dml操作的行级锁的等待时间--default-authentication-plugin=mysql_native_password

-------------------------------------分割线----------------------------------------
本着多试几次的态度,我将–default-authentication-plugin=mysql_native_password 重新加上了,

version: '3.5'
services:stargate:image: ubuntu:18.04restart: alwaysworking_dir: /stargatevolumes:- ./stargate:/stargateports:- 18080:8080command: ./stargate dev.yamlnetworks:bridge_net:ipv4_address: ${BRIDGE_SUBNET_PREFIX}.03mysql:image: mysql:8.0restart: alwaysvolumes:- mysql_data:/var/lib/mysqlports:- "13306:3306"command: --default-authentication-plugin=mysql_native_passwordenvironment:- MYSQL_USER= "root"- MYSQL_PASSWORD= "123456"- MYSQL_ROOT_PASSWORD= "123456"- MYSQL_ROOT_HOST= "%"networks:bridge_net:ipv4_address: ${BRIDGE_SUBNET_PREFIX}.02
volumes:mysql_data: {}
networks:bridge_net:external: truename: ${BRIDGE_NET}

因为知道配置网络后容器可以通过容器名访问,于是想到是不是端口也要用内部端口,于是将13306改为了3306,

name: "stargate"
mode: "debug"
port: 8080
version: "v0.0.1"
start_time: "2022-08-23"
machine_id: 1
OwnerEmail: "936135768@qq.com"
enableHttps: falselog:level: "info"
#  filename: "stargate.log"
#  max_size: 200
#  max_age: 30
#  max_backups: 7
mysql:host: mysqlport: 3306user: "root"password: "123456"dbname: "stargate"max_open_conns: 200max_idle_conns: 50

结果竟然成功了。
但是从日志可以看到是有了几次错误之后才成功的。为什么会先错几次才成功,不清楚。

[root@ecs-51ff home]# docker-compose logs
Attaching to home_mysql_1, home_stargate_1
mysql_1     | 2022-09-20 10:05:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.30-1.el8 started.
mysql_1     | 2022-09-20 10:05:39+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysql_1     | 2022-09-20 10:05:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.30-1.el8 started.
mysql_1     | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
mysql_1     | 2022-09-20T10:05:39.605717Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
mysql_1     | 2022-09-20T10:05:39.606759Z 0 [Warning] [MY-010918] [Server] 'default_authentication_plugin' is deprecated and will be removed in a future release. Please use authentication_policy instead.
mysql_1     | 2022-09-20T10:05:39.606777Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.30) starting as process 1
mysql_1     | 2022-09-20T10:05:39.612780Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
mysql_1     | 2022-09-20T10:05:39.728797Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
mysql_1     | 2022-09-20T10:05:39.928952Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysql_1     | 2022-09-20T10:05:39.928986Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
mysql_1     | 2022-09-20T10:05:39.930906Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
mysql_1     | 2022-09-20T10:05:39.948930Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
mysql_1     | 2022-09-20T10:05:39.949005Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.30'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
stargate_1  | 2022-09-20T10:05:39.076Z  INFO    logger/logger.go:45     init logger success
stargate_1  |
stargate_1  | 2022/09/20 10:05:39 /Users/hanpeng/Documents/metamarvel/stargate/dao/mysql/mysql.go:22
stargate_1  | [error] failed to initialize database, got error dial tcp 172.31.0.2:3306: connect: connection refused
stargate_1  | 2022-09-20T10:05:39.077Z  ERROR   mysql/mysql.go:24       mysql connect failed... {"error": "dial tcp 172.31.0.2:3306: connect: connection refused"}
stargate_1  | init mysql failed, err:dial tcp 172.31.0.2:3306: connect: connection refused
stargate_1  | 2022-09-20T10:05:39.449Z  INFO    logger/logger.go:45     init logger success
stargate_1  |
stargate_1  | 2022/09/20 10:05:39 /Users/hanpeng/Documents/metamarvel/stargate/dao/mysql/mysql.go:22
stargate_1  | [error] failed to initialize database, got error dial tcp 172.31.0.2:3306: connect: connection refused
stargate_1  | 2022-09-20T10:05:39.450Z  ERROR   mysql/mysql.go:24       mysql connect failed... {"error": "dial tcp 172.31.0.2:3306: connect: connection refused"}
stargate_1  | init mysql failed, err:dial tcp 172.31.0.2:3306: connect: connection refused
stargate_1  | 2022-09-20T10:05:39.912Z  INFO    logger/logger.go:45     init logger success
stargate_1  |
stargate_1  | 2022/09/20 10:05:39 /Users/hanpeng/Documents/metamarvel/stargate/dao/mysql/mysql.go:22
stargate_1  | [error] failed to initialize database, got error dial tcp 172.31.0.2:3306: connect: connection refused
stargate_1  | 2022-09-20T10:05:39.913Z  ERROR   mysql/mysql.go:24       mysql connect failed... {"error": "dial tcp 172.31.0.2:3306: connect: connection refused"}
stargate_1  | init mysql failed, err:dial tcp 172.31.0.2:3306: connect: connection refused
stargate_1  | 2022-09-20T10:05:40.577Z  INFO    logger/logger.go:45     init logger success
stargate_1  | 2022-09-20T10:05:40.582Z  INFO    mysql/mysql.go:32       Init mysql success...
stargate_1  | 2022-09-20T10:05:40.590Z  INFO    mysql/mysql.go:34       Init SYS_DIC success...
stargate_1  | 2022-09-20T10:05:40.590Z  ERROR   miniocli/minioInit.go:31        Init minioclient success...
stargate_1  | [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
stargate_1  |  - using env:     export GIN_MODE=release
stargate_1  |  - using code:    gin.SetMode(gin.ReleaseMode)
stargate_1  | [GIN-debug] GET    /                         --> stargate/router.SetupGinRouter.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /ping                     --> stargate/router.SetupGinRouter.func2 (2 handlers)
stargate_1  | [GIN-debug] GET    /swagger/*any             --> github.com/swaggo/gin-swagger.CustomWrapHandler.func1 (2 handlers)
stargate_1  | [GIN-debug] POST   /api/kol/add              --> stargate/controller.AddKolHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/kol/findkol          --> stargate/controller.FindKolHandler (2 handlers)
stargate_1  | [GIN-debug] GET    /api/kol/ranking          --> stargate/controller.KolRankHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/kol/confirm          --> stargate/controller.KolConfirmHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/project/add          --> stargate/controller.AddProjectHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/project/findproject  --> stargate/controller.FindProjectHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/task/add             --> stargate/controller.AddTaskHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/task/findtask        --> stargate/controller.FindTaskHandler (2 handlers)
stargate_1  | [GIN-debug] PUT    /api/task/update          --> stargate/controller.TaskUpdateHandler (2 handlers)
stargate_1  | [GIN-debug] GET    /api/task/mytask          --> stargate/controller.MyTaskHandler (2 handlers)
stargate_1  | [GIN-debug] GET    /api/function/system_dic  --> stargate/controller.DictionaryHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/function/sendnotice  --> stargate/controller.NoticeHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/function/smartmatch  --> stargate/controller.MatchHandler (2 handlers)
stargate_1  | [GIN-debug] GET    /api/function/firstpage   --> stargate/controller.FirstpageHandler (2 handlers)
stargate_1  | [GIN-debug] POST   /api/function/uploadfile  --> stargate/controller.UploadFileHandler (2 handlers)
stargate_1  | [GIN-debug] GET    /api/function/downloadfile --> stargate/controller.DownloadFileHandler (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/             --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/cmdline      --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/profile      --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)
stargate_1  | [GIN-debug] POST   /debug/pprof/symbol       --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/symbol       --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/trace        --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/allocs       --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/block        --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/goroutine    --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/heap         --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/mutex        --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
stargate_1  | [GIN-debug] GET    /debug/pprof/threadcreate --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
stargate_1  | [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
stargate_1  | Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
stargate_1  | [GIN-debug] Listening and serving HTTP on :8080

为了测试是否真的连上了数据裤,使用curl做个测试:

[root@ecs-51ff ~]# curl http://127.0.0.1:18080/api/function/firstpage
{"code":200,"msg":"success","data":{"kolnum":7,"projectnum":34,"tournamentsnum":16}}[root@ecs-51ff ~]#
[root@ecs-51ff ~]# curl -H "Content-Type: application/json" -X POST -d '{"address":[""],"attribute":1}' http://localhost:18080/api/function/sendnotice
{"code":200,"msg":"success"}[root@ecs-51ff ~]# curl -H "Content-Type: application/json" -X POST -d '{"address":[""],"attribute":1}' http://localhost:18080/api/func
[root@ecs-51ff ~]# curl -H "Content-Type: application/json" -X POST -d '{"address":"811","name":"hello","email":"hello","url":"hello url","contact":"119"}' http://localhost:18080/api/project/add
{"code":200,"msg":"success"}[root@ecs-51ff ~]#

docker exec 进入mysql容器查看是否有新数据添加进来

真的有数据添加进来。


现在打算down掉,重新测试是哪个配置起了作用.
经过测试并不是command: --default-authentication-plugin=mysql_native_password
这句起了作用。而是正确配置了端口。
于是想到了是否容器外访问就是要127.0.0.1:13306。测试了下依然错误。
所以在go项目的配置文件里 就用docker-compose 里的服务名+容器内端口访问,即:mysql:3306

mysql:host: mysqlport: 3306user: "root"password: "123456"dbname: "stargate"max_open_conns: 200max_idle_conns: 50

虽然暂时把服务起来了,但是还有几个问题没有解决:
1 连接服务器的时候为啥还会有两次报错?
2 什么原因造成的只能用服务名和内部端口访问?(这个可以归结为对docker-compose 的不熟悉和对原理知识的空缺)
3 貌似compose的文件输入格式还有 : 和 = 的区别 。- 和 – 貌似也有区别。
两个月没弄过docker-compose了 本来自信满满 没想到炸出来这么多知识盲区
求一个熟知docker-compose的大佬来指教指教~~


更新:
docker-compose 起的服务之间不能用127.0.0.1去通信 !
因为这些个服务每个都是独立运行的linux系统 这个时候用127.0.0.1 去通信别的服务 是在这个宿主容器上的127.0.0.1 而不是宿主服务器机的127.0.0.1 所以当然找不到
所以 如果想实现服务间通信 有两种方法:

一是  用公网ip+暴露的外部端口  进行通信 如:94.64.83.175:13306 这在任何条件下 都是可行的
二是  用docker network 相关命令 建立一个服务间的通信网络,即bridge模式的通信网络,在这个网络内 可以直接用 服务名+内部端口 如:mysql:3306 通信

通常来说,
同一台主机的服务之间用内部通信方式最为方便高效,使用内部通信方式即可。
而外部通信的方式则用于与外部公网服务的通信


docker 有三种模式的通信网络
host bridge none
使用host的话 即使用宿主机的网络 不需要代理端口 ,将服务对外暴露,直接就可通信、
同时注意这个时候docker-compose文件里就不需要写port了 ,同时将networks 改为:network_mode: host

version: '3.5'
services:stargate:image: ubuntu:18.04restart: alwaysworking_dir: /stargatevolumes:- ./stargate:/stargate# ports:#   - 18181:8181command: ./stargate dev.yamlnetwork_mode: host

这里另外一个坑要注意就是:host模式用宿主机端口通信 只支持 linux系统。

Host 模式只支持 Linux 系统,Windows 和 macOS 此参数无效。

不支持Docker for Mac,Docker for Windows或Docker EE for Windows Server。

如Docker For Mac的实现和标准Docker规范有区别,Docker For Mac的Docker Daemon是运行于虚拟机(xhyve)中的, 而不是像Linux上那样作为进程运行于宿主机,因此Docker For Mac没有docker0网桥,不能实现host网络模式,host模式会使Container复用Daemon的网络栈(在xhyve虚拟机中),而不是与Host主机网络栈,这样虽然其它容器仍然可通过xhyve网络栈进行交互,但却不是用的Host上的端口(在Host上无法访问)。bridge网络模式 -p 参数不受此影响,它能正常打开Host上的端口并映射到Container的对应Port。

docker-compose部署服务网络通信问题相关推荐

  1. docker compose部署服务

    1 用docker compose部署服务 - 需求:假如现在我们手里有很多容器,每个容器对应每个服务,有nginx容器,redis容器,mysql容器等.现在我们需要批量化的去管理,批量启动,停止, ...

  2. Tensorflow Serving Docker compose 部署服务细节(Ubuntu)

    [摘要] Tensorflow Serving 是tf模型持久化的重要工具,本篇介绍如何通过Docker compose搭建并调试TensorFlow Serving TensorFlow Servi ...

  3. Docker Compose部署GitLab服务,搭建自己的代码托管平台(图文教程)

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  4. 使用Docker Compose 部署Nexus后初次登录账号密码不正确,并且在nexus-data下没有admin.password

    场景 Ubuntu Server 上使用Docker Compose 部署Nexus(图文教程): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/ ...

  5. Ubuntu Server 上使用Docker Compose 部署Nexus(图文教程)

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  6. 使用Docker Compose部署SpringBoot应用

    使用Docker Compose部署SpringBoot应用 原创: 梦想de星空 macrozheng 6月19日 Docker Compose是一个用于定义和运行多个docker容器应用的工具.使 ...

  7. Docker - 使用Docker Compose部署应用

    简介 Docker Compose是一个基于Docker Engine进行安装的Python工具.该工具使得用户可以在一个声明式的配置文件中定义一个多容器的应用,在Docker节点上,以单引擎模式(S ...

  8. Kafka:Docker Compose部署Kafka集群

    创建目录用于存放Docker Compose部署Kafka集群的yaml文件: mkdir -p /root/composefile/kafka/ 写入该yaml文件: vim /root/compo ...

  9. ZooKeeper :Docker Compose部署ZooKeeper集群

    用于Docker Compose部署ZooKeeper集群的yaml文件: version: '3' networks:zookeeper-networks:driver: bridgeservice ...

  10. RabbitMQ:Docker Compose部署RabbitMQ

    创建目录,用于存放Docker Compose部署RabbitMQ的yaml文件: mkdir -p /root/composefile/rabbitmq 写入该yaml文件: vim /root/c ...

最新文章

  1. python 环境常用指令(updating...)
  2. js reduce数组循环相加x+y
  3. 奥鹏C语言专科在线作业答案,电子科大12春《C语言(专科)》在线作业三
  4. 嵌入式视频处理基础(四)
  5. Windows server 2012 hyper-v 的实时迁移
  6. Flutter高级第7篇:点击穿透问题、页面禁止左右滑动
  7. 多媒体会议系统中的延迟
  8. 读《概率论与数理统计(陈希孺)》关于几何概率与伯特兰悖论的随笔
  9. 芒果tv视频抓包分析
  10. 剑指offer 数组中只出现一次的数字
  11. 怎样做风险评估?风险评估有哪些具体实施流程?
  12. 电影资源 BT PT下载的电影命名 规则 资源 详解
  13. Android Parcel对象详解
  14. MHA Failover测试-上
  15. 数据治理【数据安全管理】
  16. Vue简明实用教程(13)——Vue的生命周期
  17. OKHttpUitls工具包post请求
  18. JavaWeb-05 jQuery
  19. 偏微分符号 ∂ 的说明
  20. Ubuntu安装ibus万能五笔

热门文章

  1. 中国式家长如何成为计算机科学家,中国式家长清华大学怎么弄_一周目上清华流程介绍_3DM单机...
  2. 智能便捷的在线考试系统
  3. tornado python web上传大视频文件
  4. 125KHz 100cm ID 读卡电路_考试答题卡读卡器网站
  5. Security: Inside Windows Vista User Account Control | Microsoft Docs
  6. Tim/QQ登录超时,请检查您的网络或者本机防火墙设置
  7. 计算机知识竞赛宣传标题语,知识竞赛参赛宣言标语
  8. 基于openMV的口罩检测
  9. php变量赋值作业,变量及变量的赋值作业
  10. c语言单链表的查找,单链表的查找、建立操作(C语言)