添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

flask工具搭建web微服务

Flask是一个Python编写的Web 微框架,让咱们可使用Python语言快速实现一个网站或Web服务。
参考自Flask官方文档:
https://flask.palletsprojects.com/en/0.12.x/
参考中文文档官方文档: https://dormousehole.readthedocs.io/en/latest/

1.安装flask

需要python 环境,这个自行安装

1
pip install flask

简单上手

最小的 Flask 应用以下flask_demo.py

1
2
3
4
5
6
7
8
9
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello World'

if __name__ == '__main__':
app.run()

代码解析:
一、首先咱们导入了 Flask 类。 该类的实例将会成为咱们的 WSGI 应用。 , WSGI作为一个规范,定义了Web服务器如何与Python应用程序进行交互,使得使用Python写的Web应用程序可以和Web服务器对接起来。
二、接着咱们建立一个该类的实例。第一个参数是应用模块或者包的名称。若是你使用 一个单一模块(就像本例),那么应当使用 name ,由于名称会根据这个 模块是按应用方式使用仍是做为一个模块导入而发生变化(多是 ‘main’ , 也多是实际导入的名称)。这个参数是必需的,这样 Flask 才能知道在哪里能够 找到模板和静态文件等东西
三、而后咱们使用 route() 装饰器来告诉 Flask 触发函数的 URL 。
四、函数名称被用于生成相关联的 URL 。函数最后返回须要在用户浏览器中显示的信息

运行结果:

1
2
3
4
5
6
* Serving Flask app "flask_demo" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

打开链接查看 访问: http://127.0.0.1:5000/

说明

1
app.route(rule, options)

rule 参数表示与该函数的URL绑定。
options 是要转发给基础Rule对象的参数列表。
在上面的示例中,’/ ‘ URL与hello_world()函数绑定。所以,当在浏览器中打开web服务器的主页时,将呈现该函数的输出。

Flask类的run()方法在本地开发服务器上运行应用程序。

1
app.run(host, port, debug, options)

全部参数都是可选的web

host:要监听的主机名。 默认为127.0.0.1(localhost)。设置为“0.0.0.0”以使服务器在外部可用
port :默认值为5000
debug:默认为False。 若是设置为True,则提供调试信息,能够自动重载代码并显示调试信息
options:要转发到底层的Werkzeug服务器。

注意,False 和True 首字母大写

默认状况下,Flask绑定IP为127.0.0.1,端口为5000。也能够经过下面的方式自定义

1
app.run(host='0.0.0.0', port=80, debug=True)

0.0.0.0表明电脑全部的IP。80是HTTP网站服务的默认端口。
什么是默认?好比,咱们访问网站
http://www.example.com,实际上是访问的http://www.example.com:80,只不过:80能够省略不写。

Flask HTTP方法

Web 应用使用不一样的 HTTP 方法处理 URL 。当你使用 Flask 时,应当熟悉 HTTP 方法。 缺省状况下,一个路由只回应 GET 请求。 可使用 route() 装饰器的 methods 参数来处理不一样的 HTTP 方法:

方法 描述
GET 以未加密的形式将数据发送到服务器,最多见的方法。
HEAD 和GET方法相同,但没有响应体。
POST 用于将HTML表单数据发送到服务器,POST方法接收的数据不禁服务器缓存。
PUT 用上传的内容替换目标资源的全部当前表示。
DELETE 删除由URL给出的目标资源的全部当前表示。
默认状况下,Flask路由响应GET请求。可是,能够经过为route()装饰器提供方法参数来更改此首选项。

为了演示在URL路由中使用POST方法,首先让咱们建立一个HTML表单,并使用POST方法将表单数据发送到URL。
将如下脚本另存为login.html

1
2
3
4
5
6
7
8
9
10
11
<html>
<body>

<form action = "http://localhost:5000/login" method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>

</body>
</html>

运行如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, redirect, url_for, request
app = Flask(__name__)

@app.route('/success/<name>')
def success(name):
return 'welcome %s' % name

@app.route('/login',methods = ['POST', 'GET'])
def login():
if request.method == 'POST':
user = request.form['nm']
return redirect(url_for('success',name = user))
else:
user = request.args.get('nm')
return redirect(url_for('success',name = user))

if __name__ == '__main__':
app.run(debug = True)

在浏览器中打开login.html,在文本字段中输入name,而后单击提交。
在这里插入图片描述
表单数据将POST到表单标签的action子句中的URL。

http://localhost/login映射到login()函数。因为服务器经过POST方法接收数据,所以经过如下步骤得到从表单数据得到的“nm”参数的值:
表单数据将POST到表单标签的action子句中的URL。

1
user = request.form['nm']

它做为变量部分传递给’/ success’ URL。浏览器在窗口中显示welcome消息。
在这里插入图片描述
在login.html中将方法参数更改成’GET’,而后在浏览器中再次打开它。服务器上接收的数据是经过GET方法得到的。经过如下的步骤得到’nm’参数的值:

1
User = request.args.get('nm')

这里,args是包含表单参数对及其对应值对的列表的字典对象。与’nm’参数对应的值将像以前同样传递到’/ success’ URL。

若是通过json 的方式获取数据,则直接使用data1 = request.get_data() 获取字符传,然后使用json.loads(data2)进行转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask, jsonify, request, abort
import json
@app.route('/ana', methods=['GET', 'POST'])
def call_analysis():
print("Hello, World!")

data1 = request.data #----获取的是字符串
#print(data1)
data2 = request.get_data() #----获取的是字符串
#print(data2)
j_data = json.loads(data2) #-----load将字符串解析成json
# print(j_data)
# print(j_data['base64'])

# return jsonify(j_data)

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

模型训练yolov5环境搭建

本文将介绍yolov5从环境搭建到模型训练的整个过程

目录

1.anconda环境搭建
2.yolov5下载
3.素材整理
4.模型训练
5.效果预测

建议提前下载的一些工具或安装包
anconda下载地址:
https://www.anaconda.com/products/individual#Downloads
yolov5源码下载地址: https://github.com/ultralytics/yolov5

1.anconda环境搭建

提醒:所有操作都是在anconda的yolo的环境下进行的,在创建yolo环境后,之后每次进入CMD都需要切换到yolo环境中去(否则进入默认的base环境中)

https://www.anaconda.com/products/individual#Downloads
下载对应版本anconda即可,这里不介绍anconda安装过程了。
安装可以参考: https://blog.csdn.net/qq_43674360/article/details/123396415

anconda安装好后,conda可以创建多个运行环境,默认是base环境。这里为yolo创建一个环境。
打开CMD命令行,为yolov5创建一个环境,注意这里用的python版本是3.8,版本过低后面可能会报错

1
conda create -n yolo python=3.8
1
conda info -e

即可看到刚刚创建的yolo环境

1
2
3
4
5
6
7
8
D:\vsCodeWorkspace\python_test_20230415>conda info -e
# conda environments:
#
fl C:\Users\dell\.conda\envs\fl
mind07py375 C:\Users\dell\.conda\envs\mind07py375
myenv C:\Users\dell\.conda\envs\myenv
yolo C:\Users\dell\.conda\envs\yolo
base C:\python20230415\Anaconda3
1
activate yolo

即可切换到的yolo环境下了。记住退出CMD或者切换CMD窗口之后,如果想要进入yolo环境,都需要运行activate yolo指令。不然默认是在base环境下。
除此之外,进行yolo模型训练代码的编写需要用到jupyter notebook,所以需要在yolo环境下进行安装

1
conda install jupyter notebook

安装完成之后,只需要在yolo环境下输入

1
jupyter notebook

就会打开notebook,自动跳转到浏览器,打开notebook界面,之后会在notebook里进行训练yolo模型

yolov5下载

下载yolov5源码: https://github.com/ultralytics/yolov5
解压,可以看到里面有requirements.txt文件,里面记录了需要安装的包,这个txt文件可以帮助一键下载这些依赖包。

文件夹里也包含了train.py文件,这个也接下来训练yolo模型需要用到的启动文件。

接着上面的requirement.txt,介绍如何安装里面需要安装的依赖。首先打开下载好的yolov5_master 文件夹,在上面输入cmd回车,可以直接在该文件夹目录下打开命令行。

在cmd命令行打开之后,大家千万记得要切换到的yolo环境下,不然就安装到base环境中去了。

1
activate yolo
1
pip install -r requirements.txt

就会自动把这些依赖安装好了。接下来开始训练yolo模型了。

整理yolov5模型

为了完成训练工作,需要将训练的图片按照指定的格式进行整理,
详细参照yolov5官方指南:
https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data

这里也简要介绍一遍过程,然后也为大家避坑,在训练前首先需要采集图片样本,然后再对图片中的待识别物体进行标注。
首先需要建立如下的文件夹images,labels和A.yaml文件:
D:\VSCODEWORKSPACE\PYTHON_TEST_20230415\YOLO_A
├─images
└─labels
└─A.yaml
所有文件放在yolo_A文件夹下,子文件夹images用来存放样本图片,labels文件夹用来存储标注信息。A.yaml文件用来存放一些目录信息和标志物分类。

这次测试的检测哆啦A梦的头像,采集了50张哆啦A梦的样本,放到images文件夹下:

图片的标注

接下来就要进行图片的标注工作了,图片标注用到了一个名为labelimg的工具:
https://github.com/tzutalin/labelImg
大家下载解压之后,首先要做的是删除
labelImg-master\data\predefined_classes.txt
txt文件中的内容,不然等会标记的时候会自动添加一些奇怪的类别。

然后在labelImg-master文件夹下打开cmd,进入的yolo环境中,然后还需要在yolo环境中安装一些labelimg运行需要的依赖,依次输入

1
2
3
4
activate yolo
conda install pyqt=5
conda install -c anaconda lxml
pyrcc5 -o libs/resources.py resources.qrc

现在,已经在yolo环境中安装好labelimg的依赖环境了,输入

1
python labelimg.py

即可进入的界面中来。进入之后,首先先把一些选项勾上,便于标记。
然后,最重要的是把标记模式改为yolo。

1
2
3
4
5
6
7
8
View 中标记前五个
Auto Save mode
Single Class mode
Display Labels
Show/Hide Label Panel
Advanced Mode

在保存下面的标记模式改为yolo

之后点击Open dir选择图片所在的images文件夹,选择之后会弹窗让你选择labels所在的文件夹。当然如果选错了,也可以点change save dir进行修改。

然后软件右上角打开这个选项,当标记图片后,就会自动帮归类到A了

现在就可以开始进行标记了,常用的快捷键,用主要wad三个键

1
2
3
4
5
6
7
8
9
10
11
12
13
Ctrl + u	Load all of the images from a directory
Ctrl + r Change the default annotation target dir
Ctrl + s Save
Ctrl + d Copy the current label and rect box
Ctrl + Shift + d Delete the current image
Space Flag the current image as verified
w Create a rect box
d Next image
a Previous image
del Delete the selected rect box
Ctrl++ Zoom in
Ctrl-- Zoom out
↑→↓← | Keyboard arrows to move selected rect box

通过鼠标拖拽框选即可标注:

所有图片标注好之后,再来看的labels文件夹,可以看到很多txt文件。每个文件都对应着标记的类别和框的位置:

最后还要做的是建立yaml文件,文件的位置也不要放错:

文件里面内容如下,其中train和val都是images的目录,labels的目录不用写进去,会自动识别。nc代表识别物体的种类数目,names代表种类名称,如果多个物体种类识别的话,可以自行增加。

1
2
3
4
5
6
7
8
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: ../yolo_A/images/
val: ../yolo_A/images/
# number of classes
nc: 1

# class names
names: ['A meng']

到目前,的训练的图片材料就已经准备好了。

出现问题解决

labelImg闪退的高效解决方法
解决方法:
1.labelImg软件安装路径中不能出现中文路径,如果出现,换个英文的路径,(一般这样情况比较多)。
2.进入到C:\Users\Administrator,将.labelImgSettings.pkl文件删除,重新运行即可。(找不到可以目录下进行搜索)
3:使用labelImg 所在 anaconda 终端环境中依次执行以下命令
pip install PyQt5 -i
https://pypi.tuna.tsinghua.edu.cn/simple/
pip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install labelImg -i https://pypi.tuna.tsinghua.edu.cn/simple/
最后在中输入python labelimg.py启动。

yolov5模型训练

现在开始训练模型
首先进行模块导入

1
2
3
4
5
6
7
8
9
10
# 若是没有进行过下载,则进行下载yolov5源码进行
# git clone https://github.com/ultralytics/yolov5 # clone repo
# cd yolov5
# pip install -qr requirements.txt # install dependencies
# 云上环境需要,本地不需要进行,继续往后就行
# import torch
# from IPython.display import Image, clear_output # to display images

# clear_output()
# print('Setup complete. Using torch %s %s' % (torch.__version__, torch.cuda.get_device_properties(0) if torch.cuda.is_available() else 'CPU'))

后把的的素材yolo_A文件夹放到yolov5根目录

然后一下代码可以测试能否正常工作,顺带会下载yolov5s.pt文件,这个文件后面训练的时候会用到

1
2
 python detect.py --weights yolov5s.pt --img 640 --conf 0.25 --source data/images/
# Image(filename='runs/detect/exp/zidane.jpg', width=600)

然后在 yolov5/runs/detect/exp 文件夹可以看到识别结果

接下来就要开始训练模型了:

1
python train.py --img 640 --batch 50 --epochs 100 --data ../yolo_A/A.yaml --weights yolov5s.pt --nosave --cache

注意:../yolo_A/A.yaml 路径按照需要的路径进行调整

训练完成后,们可以看到训练结果保存的位置:

在对应exp文件下可以看到用训练集做预测的结果:

1
Image(filename='runs/train/exp2/test_batch0_pred.jpg', width=800)  # test batch 0 predictions

现在们用训练出来的结果找一张网图做测试(文件名和导出预测文件地址不一定相同,但是相似,自行寻找)

1
2
python detect.py --weights /content/yolov5/runs/train/exp2/weights/best.pt --img 640 --conf 0.25 --source ../test2.jpg
#Image(filename='runs/detect/exp4/test2.jpg', width=600)

出现问题解决

DLL load failed: 页面文件太小,无法完成操作

需要把电脑无用程序都关闭。还有python.exe注意不能同时被2个程序使用,

提示页面文件太小,说明虚拟内存不够了,可以关掉一些进程,

或者把虚拟内存往大调一下(此处参考网上修改) http://www.nndssk.com/xtwt/122595A9Q5mb.html

OSError: [WinError 1114] 动态链接库(DLL)初始化例程失败。 Error loading “C:\Users\dell.conda\envs\yolo\lib\site-packages\torch\lib\shm.dll” or one of its dependencies.

RuntimeError: [enforce fail at C:\actions-runner_work\pytorch\pytorch\builder\windows\pytorch\c10\core\impl\alloc_cpu.cpp:72] data. DefaultCPUAllocator: not enough memory: you tried to allocate 49152000 bytes.

修改train.py中 batchsize和worker,将数值减少,

1
2
3
4
5
6
7
8
9
10
parser.add_argument('--hyp', type=str, default=ROOT / 'data/hyps/hyp.scratch-low.yaml', help='hyperparameters path')
parser.add_argument('--epochs', type=int, default=100, help='total training epochs')
#parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs, -1 for autobatch')
parser.add_argument('--batch-size', type=int, default=2, help='total batch size for all GPUs, -1 for autobatch')

parser.add_argument('--optimizer', type=str, choices=['SGD', 'Adam', 'AdamW'], default='SGD', help='optimizer')
parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
#parser.add_argument('--workers', type=int, default=8, help='max dataloader workers (per RANK in DDP mode)')
parser.add_argument('--workers', type=int, default=2, help='max dataloader workers (per RANK in DDP mode)')
parser.add_argument('--project', default=ROOT / 'runs/train', help='save to project/name')

TabError: Inconsistent use of tabs and spaces in indentation

首先这个错误的意思是:在缩进的时候,使用了错误的空格和tab

造成这个错误的原因是代码前先用了空格然后再用tab完成了对齐,也就是说,这种错误产生的原因正是由于空格或者tab缩进造成的。

将空格删除,直接使用tab完成缩进,发现程序正常运行;

再试一下空格缩进,然后发现还是报错了,同样TabError: Inconsistent use of tabs and spaces in indentation。

注意,整个代码一定使用相同的,都用空格,或者都用tab

AssertionError: Label class 1 exceeds nc=1 in data/steel.yaml. Possible class labels are 0-0

仔细阅读报错内容可以发现:类别与标签序号不匹配(自定义数据集只有一类)
经过的仔细思考,猜测是在生成labels时出现了问题,通过阅读生成labels的脚本,找到问题如下:
查看 labels 首行首个字母是2 不是0 ,需要将2修改为 0

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

windows cmd 查看文件目录树

1.打开命令终端

点击底部栏 Windows图标,选择“Windows系统”中的“命令提示符”
右键以管理员身份运行

2.输入命令

tree:不输入任何参数,输出一棵目录树

1
tree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
D:.
│ config.json

├─ets
│ ├─FormAbility
│ │ form.ts
│ │
│ ├─MainAbility
│ │ │ app.ets
│ │ │
│ │ └─pages
│ │ index.ets
│ │ SecondPage.ets
│ │
│ ├─model
│ │ Logger.ets
│ │
│ └─SecondAbility
│ │ app.ets
│ │
│ └─pages
│ index.ets

├─js
│ ├─widget
│ │ ├─common
│ │ ├─i18n
│ │ └─pages
│ │ └─index
│ │ index.css
│ │ index.hml
│ │ index.json
│ │
│ └─widget1
│ ├─common
│ │ widget.png
│ │
│ ├─i18n
│ │ zh-CN.json
│ │
│ └─pages
│ └─index
│ index.css
│ index.hml
│ index.json

└─resources
├─base
│ ├─element
│ │ color.json
│ │ string.json
│ │
│ └─media
│ icon.png

├─en_US
│ └─element
│ string.json

├─rawfile
└─zh_CN
└─element
string.json

注意的一点是,符号需要是英文格式,并且中间拥有空格,否则提示:参数无效,无法操作识别等情况发生。

3.提示

1
tree /?:命令提示

Linux查看目录树形结构

1.安装

安装tree。

1
yum -y install tree

2.验证

查看是否安装成功

1
yum list installed  tree

3.查看

执行tree命令查看目录树形结构

1
tree

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

电池损耗

1.打开命令终端

点击底部栏 Windows图标,选择“Windows系统”中的“命令提示符”
右键以管理员身份运行

2.输入命令

进入命令符对话框后可输入命令

1
powercfg /batteryreport /output "C:\battery_report.html"

注意的一点是,符号需要是英文格式,并且中间拥有空格,否则提示:参数无效,无法操作识别等情况发生。

2.查看

提示操作成功后,进入电脑找到保存路径 C:\ ,可发现新增【battery_report.html】网页文件。

可了解到电池基本概况:
电脑名称、系统名称、保存时间等;
当前状态下的电池容量概况;
可以看到近三天的电池充电情况;
详细时间段的电池使用记录;

磁盘速度

1.打开命令终端

点击底部栏 Windows图标,选择“Windows系统”中的“命令提示符”
右键以管理员身份运行

2.输入命令

进入命令符对话框后可输入命令

1
winsat disk -ran -write –drive c

即可查看磁盘c的速度,若若需要查看其他盘的速度将后面的“c” 改为其他盘即可

1
winsat disk -ran -write –drive d

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

简介

instantbox是一款非常实用的项目,它能够让你在几秒内启动一个主流的 Linux 系统,随起随用,支持 Ubuntu, CentOS, Arch Linux, Debian, Fedora 和 Alpine,通过 WebShell 访问,简单快捷,适合于演示、测试、体验等场合。

环境

安装 Docker
安装 Docker 与 Docker-Com­pose

1
2
3
4
5
6
7
8
curl -fsSL https://get.docker.com | bash -s docker
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
systemctl start docker
systemctl enable docker
```
## 安装instantbox
使用 Docker-Compose,则可以直接下载 docker-compose 文件,并跳过安装脚本。

wget https://raw.githubusercontent.com/instantbox/instantbox/master/docker-compose.yml

1
修改 docker-compose.yml 中SERVERURL,和对外访问的端口

version: ‘3’

services:
server:
image: instantbox/instantbox:latest
container_name: instantbox_server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- SERVERURL=<替换为服务器的IP>
networks:
- instantbox_net

frontend:
image: instantbox/instantbox-frontend:latest
container_name: instantbox_frontend
links:
- server
ports:
- <替换为端口>:80
networks:
- instantbox_net

cron:
image: instantbox/cron:latest
container_name: instantbox_cron
links:
- frontend
environment:
- CRON_STRINGS=* * * * * wget -qO /dev/null http://frontend/api/v2/superinspire/prune
networks:
- instantbox_net

networks:
instantbox_net:

1
2

现在运行:

docker-compose up -d

```
Docker 将下载最新的 Instantbox 映像,
使用 Instantbox 在浏览器中访问 Linux 发行版
如果从同一本地网络上的另一台计算机访问,则需要查找主机的本地 IP 地址。

访问IP:端口

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

一、Linux上卸载JDK

1. Linux删除自带的jdk

在我们安装linux虚拟机时可能会自带安装一个jdk,这时候如果想要干净方便的删除jdk的话可用以下方法

第一步 :先查看自带的jdk有几个,用命令:

1
rpm -qa | grep -i java

意思是查询所安装的带有java的rpm软件包。

第二步:去删除,命令如下:

1
rpm -qa | grep -i java | xargs -n1 rpm -e --nodeps

解释:
rpm -qa:查询所安装的所有rpm包
grep -i:忽略大小写
xargs -n1:表示每次只传递一个参数
rpm -e –nodeps:强制卸载软件

第三步:编辑profile文件,去除环境变量配置

vim /etc/profile

#然后 source命令让修改后的profile文件立即生效
source /etc/profile

最后:
可以再用命令: 查看是否还在即可

1
rpm -qa | grep -i java

或者查看java版本

1
java -version

2. Linux上卸载自己安装的JDK

1.先 查看是否安装了JDK

1
java -version

2.查看jdk安装的路径

1
which java

3.卸载命令rm -rf JDK地址,比如

1
rm -rf /usr/java/jdk1.8.0_181/

4.进去/usr/java目录查看一下,ls是显示目录下文件,发现确实什么都没有了

5.接下来删除环境变量,装的时候环境变量都是在/etc/profile下面的,进入profile,把之前配置的java相关的环境变量全给删除

1
vim /etc/profile

之后 让配置文件生效。

1
source /etc/profile

二、安装jdk1.8

第一步:创建jdk安装目录(该/usr/local/src 目录是空的,最好把我们自己下载的放到这,容易区分)

1
mkdir -p /usr/local/src/jdk

第二步:查看安装程序

1
rpm -qa | grep -i jdk

若之前安装过jdk,下次安装一定把之前的删除干净

第三步:命令下载jdk包 (需要联网,下载也需要点时间)
官网下载页面:Java Downloads | Oracle

本章使用的为后缀为tar.gz的文件(不需要安装),如jdk-8u221-linux-x64.tar.gz

1
wget -O jdk-8u221-linux-x64.tar.gz https://download.oracle.com/otn/java/jdk/8u221-b11/230deb18db3e4014bb8e3e8324f81b43/jdk-8u221-linux-x64.tar.gz?AuthParam=1565847915_b5885c839380ee62ab06bf97bdb1f2c7

注意:如果上面wget命令不能用,报错:-bash: wget: command not found。执行一下该命令(安装依赖包) yum -y install wget

第四步:解压

1
tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local

系统会生成一个名为:jdk1.8.0_221 的文件夹。-C 指定安装到/usr/local 目录下

第五步:配置环境变量

1
vim /etc/profile

可以看到这个文件的内容,profile文件有点类似于windows系统里面的环境变量的配置,

shift + g 定位到最后一行

这个时候按一下a或i键,进入编辑模式

需要加的( JAVA_HOME 是jdk安装目录,和在Windows下配置一样 )

1
2
3
export JAVA_HOME=/usr/local/jdk1.8.0_221
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar

第六步:退出文件,保存
按Esc键 输入:wq 保存并退出

第七步:让配置文件生效

1
source /etc/profile

第八步:查看是否配置成功

1
java -version

若出现jdk版本号,则安装并配置环境变量成功

如果提示命令找不到的话,查看一下jdk的配置路径是否错误。

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

1.说明

Spring可以方便的集成使用 Kafka消息队列 ,
只需要引入依赖包spring-kafka,
注意版本兼容问题,
本文详细介绍SpringBoot集成Kafka的方法,
以及生产者和消费者的使用方法。

2.引入依赖

在 pom.xml 中引入Spring Kafka版本:

1
2
3
4
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>

3.配置

新增applicaion.yml如下配置:

Spring Kafka 通用配置

1
2
3
4
spring:
kafka:
# kafka连接接地址
bootstrap-servers: localhost:9092

通用配置:spring.kafka.*
下面的admin、producer、consumer、streams配置,
会覆盖通用配置 spring.kafka.* 中相同的属性。

生产者配置

1
2
3
4
5
6
7
8
spring:
kafka:
# 生产者配置
producer:
# 序列化key的类
key-serializer: org.apache.kafka.common.serialization.StringSerializer
# 反序列化value的类
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer

生产者相关配置:spring.kafka.producer.*

消费者配置

1
2
3
4
5
6
7
8
9
10
spring:
kafka:
# 消费者配置
consumer:
# 消费者所属消息组
group-id: testGroup
# 反序列化key的类
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
# 反序列化value的类
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer

消费者相关配置:spring.kafka.consumer.*

默认 value-deserializer 使用 org.apache.kafka.common.serialization.StringDeserializer ,
只支持文本消息。
使用org.springframework.kafka.support.serializer.JsonDeserializer可以让消息支持JSON。

完整applicaion.yml配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server:
port: 8028

spring:
kafka:
# kafka连接接地址
bootstrap-servers: localhost:9092
# 生产者配置
producer:
# 序列化key的类
key-serializer: org.apache.kafka.common.serialization.StringSerializer
# 反序列化value的类
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
# 消费者配置
consumer:
# 消费者所属消息组
group-id: testGroup
# 反序列化key的类
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
# 反序列化value的类
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer

4.开发代码

KafkaMQApplication.java启动类,

注意要新增 @EnableKafka 注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.yuwen.spring.kafka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.kafka.annotation.EnableKafka;

@SpringBootApplication
@EnableKafka
public class KafkaMQApplication {
public static void main(String[] args) {
SpringApplication.run(KafkaMQApplication.class, args);
}
}

生产者发送消息

Spring Kafka 提供KafkaTemplate类发送消息,
在需要的地方注入即可,
新增ProviderService.java生产者服务类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.yuwen.spring.kafka.provider;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

@Service
public class ProviderService {
public static final String TOPIC = "testTopic";

@Autowired
private KafkaTemplate<?, String> kafkaTemplate;

public void send(String message) {
// 发送消息
kafkaTemplate.send(TOPIC, message);
System.out.println("Provider= " + message);
}
}

注意指定 topic ,
以及要发送的消息内容message。

消费者接收消息

新增ConsumerService.java类,
注意使用 @KafkaListener 注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.yuwen.spring.kafka.consumer;

import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;

import com.yuwen.spring.kafka.provider.ProviderService;

@Service
public class ConsumerService {
@KafkaListener(topics = ProviderService.TOPIC, groupId = "testGroup", topicPartitions = {})
public void receive(String message) {
System.out.println("Consumer= " + message);
}
}

参数说明:
topics 与发送消息topic相同,可以指定多个
groupId 消费组唯一id
topicPartitions topic分区,可指定多个

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

kafka-compose.yml 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#docker-compose -f kafka-compose.yml up -d
#kafka-compose.yml 配置文件如下
version: '3'
services:
kafka:
container_name: kafka
image: wurstmeister/kafka:2.13-2.6.0
ports:
- "9092:9092"
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_HOST_NAME: 192.168.23.128 # need to be replaced with host ip 替换为宿主机IP
advertised.listeners: PLAINTEXT://192.168.23.128:9092 # need to be replaced with host ip 替换为宿主机IP
volumes:
- /var/run/docker.sock:/var/run/docker.sock # 容器内可以执行docker ps、docker port等命令
restart: always

zookeeper:
container_name: zookeeper
image: wurstmeister/zookeeper
ports:
- "2181:2181"
restart: always

注意:
1.KAFKA_ADVERTISED_HOST_NAME 替换为宿主机IP
2.advertised.listeners 替换为宿主机IP
3.此镜像版本,kafka默认占用1G内存,若启动不了,请检查内存足够

kafkaui-compose.yml 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#docker-compose -f kafkaui-compose.yml up -d
#kafkaui-compose.yml 配置文件如下
version: '3.0'
services:
kafka-ui:
image: provectuslabs/kafka-ui:master
container_name: kafka-ui
ports:
- 18080:8080
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=douyh
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=192.168.23.128:9092
# - KAFKA_CLUSTERS_0_PROPERTIES_SECURITY_PROTOCOL=SASL_PLAINTEXT
# - KAFKA_CLUSTERS_0_PROPERTIES_SASL_MECHANISM=PLAIN
# - KAFKA_CLUSTERS_0_PROPERTIES_SASL_JAAS_CONFIG=org.apache.kafka.common.security.plain.PlainLoginModule required username="app" password="xxxxxxxx";
# - KAFKA_CLUSTERS_0_PROPERTIES_PROTOCOL=SASL
- AUTH_TYPE="LOGIN_FORM"
- SPRING_SECURITY_USER_NAME=root
- SPRING_SECURITY_USER_PASSWORD=root

注意:
1.KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS 替换为宿主机IP

在外部浏览器可以访问 http://ip:18080/
账号:root,
密码:root

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;