使用Systemd设置程序开机自启动常见问题(以kafka和zookeeper自启动为例)


前言

上一篇主要展示了使用systemd实现自启动的步骤,同时对service文件的常用选项进行了解释,事实上借助systemd实现自启动十分简单,但是对于新手来说总会遇到这样那样的问题,这篇文章我将借助我最近遇到的一个困扰许久的自启动问题展示一些常见问题


问题解决流程

问题详述

我们团队所研发的系统是一个基于微服务架构的一站式信息系统,包括数据收集、设备的管理和检测、信息收集、分析、清洗、存储以及结构化展示、还包括分析结果的展示、存储、远程通知等等功能。

考虑到数据吞吐量和时效性,团队采用kafka这种分布式消息系统,使用kafka内置自带Zookeeper管理集群配置,这天我接到了我导的任务是让Kafka实现开机自启动以防宕机带来损失

问题处理流程

解决用户默认路径下没有Java路径的问题

第一次我很快书写好service文件如下:

[Unit]
Description=kafka
After=map-gateway.service map-zookeeper.service

[Service]
User=map
#ExecStart=/opt/map/module/eureka/zookeeper-kafka.sh
ExecStart=/opt/map/kafka/kafka_2.12-2.5.0/bin/kafka-server-start.sh /opt/map/kafka/kafka_2.12-2.5.0/config/server.properties
ExecStop=/opt/map/kafka/kafka_2.12-2.5.0/bin/kafka-server-stop.sh
#Restart=on-failure
TimeoutSec=1800
#Type=forking

[Install]
WantedBy=multi-user.target

很快我发现这个service服务运行失败,kafka启动失败,但是zookeeper启动成功

怀疑1:kafka或者zookeeper自身出了问题
方法:
	我找来学长写的一个能成功启动kafka的启动脚本,将其改造之后,把脚本地址写进了ExecStart选项中,			
	启动后依旧失败。之后我将脚本在本地运行以普通用户权限运行还是失败,和学长讨论过后得知,
	脚本中需要export进去JAVA的地址,之后在普通用户权限下执行脚本,但是依旧失败。
解决:
	我发现如果在sudo和root下运行脚本是可以成功开启Kafka的,所以kafka没问题

自然而然地我就考虑到是两种用户的权限不一样,所以是文件权限运行环境有差别(事实上只要把User选项改成root,一切问题都可以迎刃而解,但这是不推荐的)

怀疑2:文件无权限访问 
方法:
	因为被要求执行用户必须是专为这个微服务架构所分配的用户map,所以我分别对
	JAVA本体所在位置、Kafka以及脚本文件的路径进行了权限检查,全部都是map用户的755权限 
	结果还是失败而告终

事实上在很多类似于这种对于Linux较为底层的技术操作的过程中,最经常遇到的就是权限问题,它们的主要特征是报错为“XXXXXXX(Permission denied) ”,所以遇到这两个单词大概率就是需要修改文件权限

怀疑3:systemd运行时JAVA的环境出现问题(最为怀疑)
方法:
	我发现如果在map普通用户下执行“java -version”以及其他使用java的操作时
	会报“zsh: command not found: java”的错误,简单查找后我发现是需要在用户的默认路径中添加即可
	(https://blog.csdn.net/qq_41538097/article/details/107110230)
	添加完成以后不要忘记source ~/.bashrc
	之后报出“.bashrc:24: command not found: shopt”错误
	我忘记了这台测试机用的shell(命令处理器)不是默认的bash而是zsh!!!!
	立马改用~/.zshrc!!!!!
解决:
	但事与愿违,最终虽然普通用户下java -version成功,但还是无法成功启动脚本

事实上,zshrc和bashrc文件分别对应不同的shell,每个用户的 home 目录都有这个 shell 脚本,它用来存储并加载你的终端配置和环境变量,所以把JAVA的路径写入这个文件后就会在下次启动时自动加载

解决Kafka运行日志等相关联文件权限问题

在求助我导之后,我们一起对于这个问题进行更加细致的排查

步骤1:使用journal名命令查看运行单元日志
过程:
	我导提到了journal命令来查看systemd的启动详情,这让我幡然醒悟,因为
    当初学习的时候就经常用journal命令查看运行的单元的日志信息,只不过因为大部分情况下
    我都会使用systemctl status xxx来查看单元运行时信息,因为这次Kafka在status中没有任何报错
    所以我就忘掉它了,惭愧
结果:
	发现在journal日志中出现(Permission denied)错误,然后就很简单了,可以chown -R或者直接删掉日志
	java.io.FileNotFoundException: /opt/map/kafka/kafka_2.12-2.5.0/bin/../logs/log-cleaner.log (Permission denied)

错误如下图所示:
在这里插入图片描述
在这里我的问题是遗忘了journal这个强大的工具,其实是要打开journal即能够很清晰的看到运行日志,之所会出现日志权限的问题主要是因为由于Kafka自启动一直拖拖拉拉,导致团队不得不先使用root权限启动Kafka来和甲方对接数据,这就导致产生诸多衍生日志文件的所有者是root,由于我的粗心大意并没有仔细查看导致漏掉了几个日志,直接导致问题

解决Kafka运行环境不匹配的问题

大家以为问题解决了?事实上并不是,解决过文件访问权限问题之后Kafka依旧无法启动

我通过普通用户手动运行Kafka的bin目录下kafka-server-start.sh启动脚本,报出以下错误:

Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
怀疑1:JAVA环境加载失败
步骤:
	我们首先通过env命令确认普通用户下存在着JAVA路径,这样我们就确认JAVA环境
	对于用户的绑定是成功的,因此就剩下对于systemd启动文件的环境怀疑了
	我个人怀疑是systemd启动的流程,由于加载等问题导致用户的JAVA环境并没有导入进去
	因此使用了service文件中的Environment=属性,对照官方文档和网上的案例,我们更新了service文件按内容
结果:
	service运行单元启动成功

Kafka的service文件内容如下:

[Unit]
Description=kafka
After=map-gateway.service map-zookeeper.service

[Service]
User=map
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/java/jdk1.8.0_251/bin" 
#ExecStart=/opt/map/module/eureka/zookeeper-kafka.sh
ExecStart=/opt/map/kafka/kafka_2.12-2.5.0/bin/kafka-server-start.sh /opt/map/kafka/kafka_2.12-2.5.0/config/server.properties
ExecStop=/opt/map/kafka/kafka_2.12-2.5.0/bin/kafka-server-stop.sh
#Restart=on-failure
TimeoutSec=1800
#Type=forking

[Install]
WantedBy=multi-user.target

总结

在学习新技术方面,不论是一个比较复杂的新事物例如框架、软件甚至是新的编程语言,还是例如systemd这种简单易学的实用工具,我的学习思路始终是先利用一些简单的大众的教程进行入门,然后依据你遇到的困难和业务需求针对某一方面进行深入学习,例如阅读它的英文文档、在墙外寻找权威资料进行阅读,国内网站的博客相关的确是对于技术细节讲解的不是很全面(当然要能够科学上网)

针对遇到的问题要懂得抽丝剥茧,可以进行一些侥幸的尝试,譬如我再遇到这个问题的时候就曾经怀疑是否是service文件中其他属性设置错误。但还是要善于总结,这一个错误或者现象能够证明什么结论,例如我通过实验发现root权限就能够启动Kafka,这样就能够把问题确定在权限和环境上面。这样慢慢抽丝剥茧,最终就可以确定问题所在。

此外还要善于求助,大佬就是大佬,大佬带一带就能够学习很多东西,我导nb

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值