6.API验证

# 加密复习
#1.简单的对称加密,token是固定的
客户端请求:
import requests
# 1.自定义token值
token = 'cxiong_token' # token认证都是在请求头里携带
res = requests.get('http://127.0.0.1:8000/getInfo',
headers={'token': token}
)
print(res.text) # 服务端修改:autoserver/views.py
# 修改getInfo函数
def getInfo(requests):
# 数据获取
if requests.method == 'POST':
server_info = json.loads(requests.body)
print(server_info)
# for k,v in server_info.items():
# print(k,v)
return HttpResponse('OK')
# 服务端如何获取请求头里面的数据
# requests.POST\requests.FILES\requests.GET
# HTTP_TOKEN
# print(requests.META)
token = requests.META.get('HTTP_TOKEN')
server_token ='cxiong_token'
if token != server_token:
return HttpResponse('token值错误')
# 链接后台数据库获取主机名列表并返回
return HttpResponse(['c1.com', 'c2.com']) # 2. 加盐处理:动态加盐
一般使用当前时间结合token加密再发送
# client请求
# 自定义token值
token = 'cxiong_token1'
import time client_time = time.time()
tmp = '%s|%s' % (token, client_time)
print(tmp)
# 加密
import hashlib md5 = hashlib.md5() # 使用md5加密
# 传入明文数据:数据必须是bytes类型
md5.update(tmp.encode('utf8'))
# 生成密文数据
res = md5.hexdigest()
print(res)
# 将加密的密文数据发送给服务端,也需要将加密之前的明文数据也发给服务端,让服务端通过相同的方法进行比对
client_md5_token = '%s|%s' % (res, client_time)
# token认证都是请求头里携带
data = requests.get('http://127.0.0.1:8000/getInfo',
headers={'token': client_md5_token}
)
print(data.text) # 服务端处理
token = requests.META.get('HTTP_TOKEN')
server_token = 'cxiong_token'
client_md5_token,client_time = token.split('|')
print(client_md5_token,client_time)
# 加密认证
tmp = '%s|%s'%(server_token,client_time)
#加密
import hashlib
md5 = hashlib.md5()
md5.update(tmp.encode('utf8'))
res = md5.hexdigest()
print(res)
if res != client_md5_token:
return HttpResponse('token值错误') # 3.设置token失效时间
client_md5_token,client_time = token.split('|')
import time
server_time = time.time()
if server_time - client_time > 10:
return HttpResponse('token超时了')
"""大部分API验证做到第三步就可以了"""
# 4.设置token使用次数
"""
黑客可能会在失效时间之前截取并发送请求
思路:
第一次来的时候先去redis中判断是否存在
如果存在则说明token已经使用过了
不存在则添加到redis中(并且设置保存的超时时间)
"""
# 5. 固定token由服务端生成发到客户端再组合的方式(看业务是否重要了)

7.后台目录规划

# django是一款专注于开发app的框架
"""
1.api:接收数据并处理入库(API验证)
2.backend : 后台管理
# 上述两个app都需要使用模型表,那么模型表写在哪个models文件
3.repository:单独存储模型表相关代码
"""

8.模型表设计

"""
#{'board': {'status': 10000, 'data': {'manufacturer': 'Parallels Software International Inc.', 'model': 'Parallels Virtual Platform', 'sn': 'Parallels-1A 1B CB 3B 64 66 4B 13 86 B0 86 FF 7E 2B 20 30'}} 1.设计模型表的时候字段名与收集过来的字典的key保持一致
models.User.objects.create(name='jason',age=18)
d = {'name':'cxiong','age':32}
models.User.objects.create(**d) # **d将数据打散为name=jason这种模式
为了录入数据的时候可以借助于**快速录入
2.模型表设计及表关系判断,根据情况自己关联
"""
如下图

9.模型表数据录入

1.11张表相关统计表
2.数据库迁移命令
makemigrations
migrate
3.django admin后台管理
1.创建超级用户:createsuperuser
2.注册模型表
repository/admin.py
4.手动录入数据
1.业务线表
2.服务器表
对应表:

# repository/models.py
from django.db import models class UserProfile(models.Model):
"""
用户信息
python2 字符串前面需要加u: u姓名
"""
name = models.CharField(u'姓名', max_length=32)
email = models.EmailField(u'邮箱')
phone = models.CharField(u'座机', max_length=32)
mobile = models.CharField(u'手机', max_length=32)
password = models.CharField(u'密码', max_length=64) # 规定django-admin后台管理显示的中文表
class Meta:
verbose_name_plural = "用户表" def __str__(self):
return self.name class UserGroup(models.Model):
"""
用户组
"""
name = models.CharField(max_length=32, unique=True)
users = models.ManyToManyField('UserProfile') class Meta:
verbose_name_plural = "用户组表" def __str__(self):
return self.name class BusinessUnit(models.Model):
"""
业务线
"""
name = models.CharField('业务线', max_length=64, unique=True)
contact = models.ForeignKey('UserGroup', verbose_name='业务联系人', related_name='c')
manager = models.ForeignKey('UserGroup', verbose_name='系统管理员', related_name='m') class Meta:
verbose_name_plural = "业务线表" def __str__(self):
return self.name class IDC(models.Model):
"""
机房信息
"""
name = models.CharField('机房', max_length=32)
floor = models.IntegerField('楼层', default=1) class Meta:
verbose_name_plural = "机房表" def __str__(self):
return self.name class Tag(models.Model):
"""
资产标签
"""
name = models.CharField('标签', max_length=32, unique=True) class Meta:
verbose_name_plural = "标签表" def __str__(self):
return self.name class Server(models.Model):
"""
服务器信息
"""
device_type_choices = (
(1, '服务器'),
(2, '交换机'),
(3, '防火墙'),
)
device_status_choices = (
(1, '上架'),
(2, '在线'),
(3, '离线'),
(4, '下架'),
)
device_type_id = models.IntegerField('服务器类型', choices=device_type_choices, default=1)
device_status_id = models.IntegerField('服务器状态', choices=device_status_choices, default=1) cabinet_num = models.CharField('机柜号', max_length=30, null=True, blank=True)
cabinet_order = models.CharField('机柜中序号', max_length=30, null=True, blank=True) idc = models.ForeignKey('IDC', verbose_name='IDC机房', null=True, blank=True)
business_unit = models.ForeignKey('BusinessUnit', verbose_name='属于的业务线', null=True, blank=True) tag = models.ManyToManyField('Tag') hostname = models.CharField('主机名', max_length=128, unique=True)
sn = models.CharField('SN号', max_length=64, db_index=True)
manufacturer = models.CharField(verbose_name='制造商', max_length=64, null=True, blank=True)
model = models.CharField('型号', max_length=64, null=True, blank=True) manage_ip = models.GenericIPAddressField('管理IP', null=True, blank=True) os_platform = models.CharField('系统', max_length=16, null=True, blank=True)
os_version = models.CharField('系统版本', max_length=16, null=True, blank=True) cpu_count = models.IntegerField('CPU个数', null=True, blank=True)
cpu_physical_count = models.IntegerField('CPU物理个数', null=True, blank=True)
cpu_model = models.CharField('CPU型号', max_length=128, null=True, blank=True) create_at = models.DateTimeField(auto_now_add=True, blank=True) class Meta:
verbose_name_plural = "服务器表" def __str__(self):
return self.hostname class Disk(models.Model):
"""
硬盘信息
"""
slot = models.CharField('插槽位', max_length=8)
model = models.CharField('磁盘型号', max_length=32)
capacity = models.CharField('磁盘容量GB', max_length=32)
pd_type = models.CharField('磁盘类型', max_length=32)
server_obj = models.ForeignKey('Server', related_name='disk') class Meta:
verbose_name_plural = "硬盘表" def __str__(self):
return self.slot class NIC(models.Model):
"""
网卡信息
"""
name = models.CharField('网卡名称', max_length=128)
hwaddr = models.CharField('网卡mac地址', max_length=64)
netmask = models.CharField(max_length=64)
ipaddrs = models.CharField('ip地址', max_length=256)
up = models.BooleanField(default=False)
server_obj = models.ForeignKey('Server', related_name='nic') class Meta:
verbose_name_plural = "网卡表" def __str__(self):
return self.name class Memory(models.Model):
"""
内存信息
"""
slot = models.CharField('插槽位', max_length=32)
manufacturer = models.CharField('制造商', max_length=32, null=True, blank=True)
model = models.CharField('型号', max_length=64)
capacity = models.FloatField('容量', null=True, blank=True)
sn = models.CharField('内存SN号', max_length=64, null=True, blank=True)
speed = models.CharField('速度', max_length=16, null=True, blank=True) server_obj = models.ForeignKey('Server', related_name='memory') class Meta:
verbose_name_plural = "内存表" def __str__(self):
return self.slot class AssetRecord(models.Model):
"""
资产变更记录,creator为空时,表示是资产汇报的数据。
"""
asset_obj = models.ForeignKey('Server', related_name='ar')
content = models.TextField(null=True) # 新增硬盘
creator = models.ForeignKey('UserProfile', null=True, blank=True)
create_at = models.DateTimeField(auto_now_add=True) class Meta:
verbose_name_plural = "资产记录表" def __str__(self):
return "%s-%s-%s" % (self.asset_obj.idc.name, self.asset_obj.cabinet_num, self.asset_obj.cabinet_order) class ErrorLog(models.Model):
"""
错误日志,如:agent采集数据错误 或 运行错误
"""
asset_obj = models.ForeignKey('Server', null=True, blank=True)
title = models.CharField(max_length=16)
content = models.TextField()
create_at = models.DateTimeField(auto_now_add=True) class Meta:
verbose_name_plural = "错误日志表" def __str__(self):
return self.title # 注册:repository/admin.py
# 注册模型表
from django.contrib import admin
from repository import models
# Register your models here. admin.site.register(models.Server)
admin.site.register(models.Disk)
admin.site.register(models.IDC)
admin.site.register(models.NIC)
admin.site.register(models.Tag)
admin.site.register(models.Memory)
admin.site.register(models.ErrorLog)
admin.site.register(models.AssetRecord)
admin.site.register(models.UserProfile)
admin.site.register(models.UserGroup)
admin.site.register(models.BusinessUnit)

11张表

9.视图函数

# API/views.py中getinfo函数将获取客户端上传的数据采集并处理
# 资产是否存在
server_info = json.loads(requests.body)
# 通过主机名获取老的数据对应的记录
hostname = server_info['basic']['data']['hostname']
# 去数据库中查询是否有该服务器信息
old_server_info = models.Server.objects.filter(hostname=hostname).first()
# 判断
if not old_server_info:
return HttpResponse("资产不存在")

以硬盘数据为例,进行增删改查

# 先判断status状态码是否正确
# 对数据进行筛选入库
# 以硬盘数据为例
# 1.校验相应状态码
if server_info['disk']['status'] != 10000:
# 2.记录错误日志
models.ErrorLog.objects.create(
asset_obj=old_server_info,
title='%s 采集硬盘数据出错了' % hostname,
content=server_info['disk']['data']
)
# 最新硬盘数据
new_disk_info = server_info['disk']['data']
"""
new_slot_list = [0,2]
old_slot_list = [0,1]
新增:new_slot_list - old_slot_list = 2
删除:old_slot_list - new_slot_list = 1
修改:交集
"""
# 老的硬盘数据
old_disk_info = models.Disk.objects.filter(server_obj=old_server_info).all()
# 先获取新硬盘数据所有slot号
new_slot_list = list(new_disk_info.keys())
# 再获取旧的硬盘数据所有的slot号
old_slot_list = [obj.slot for obj in old_disk_info]
# 利用集合操作获取新增的数据
add_slot_list = set(new_slot_list) - set(old_slot_list)
if add_slot_list:
record_list = []
for slot in add_slot_list:
disk_res = new_disk_info[slot]
# 添加变更记录
tmp = '添加插槽是:{slot},磁盘类型:{pd_type},磁盘容量是:{capacity},磁盘型号:{model}'.format(**disk_res)
# 添加disk记录 将服务器对象直接添加到字典中,之后直接利用**打散
disk_res['server_obj'] = old_server_info
models.Disk.objects.create(**disk_res)
record_list.append(tmp)
# 将变更信息添加到记录表中
record_str = ';'.join(record_list)
models.AssetRecord.objects.create(asset_obj=old_server_info,content=record_str) return HttpResponse('OK')

硬盘增加插槽

# 硬盘数据的删除
del_slot_list = set(old_slot_list) - set(new_slot_list)
if del_slot_list:
# 数据的删除:slot__in多条数据
models.Disk.objects.filter(slot__in=del_slot_list,server_obj=old_server_info).delete()
# 记录变更
record_str = "删除的槽位slot是:%s"%(';'.join(del_slot_list))
models.AssetRecord.objects.create(asset_obj=old_server_info,content=record_str)

删除硬盘槽位

# API/views.py
# 硬盘数据的修改
up_slot_list = set(new_slot_list) & set(old_slot_list)
if up_slot_list:
record_list = []
for slot in up_slot_list:
new_disk_row = new_disk_info[slot] # 新数据 字典
# 数据库中老数据 对象
old_disk_row = models.Disk.objects.filter(slot=slot,server_obj=old_server_info).first()
# 反射:通过字符串操作对象的属性和方法(出现字符串和对象毫不犹豫使用反射的思路)
for k,new_v in new_disk_row.items():
# 1.利用反射先从老的数据中获取数据
old_v = getattr(old_disk_row,k)
# 2.判断老的数据和新的数据是否相同
if new_v != old_v:
tmp = '槽位:%s,%s由原来的%s变成了%s'%(slot,k,old_v,new_v)
record_list.append(tmp)
# 3.更新数据:将新数据设置到老的数据对象中
setattr(old_disk_row,k,new_v)
# 4.调用对象的save方法,更新数据
old_disk_row.save()
if record_list:
models.AssetRecord.objects.create(asset_obj=old_server_info,content=';'.join(record_list)) return HttpResponse('OK')

硬盘数据的修改

10.前后端分离

to B:to business  面向企业产品
to C:to client 面向客户产品
to C:
前后端分离
讲究美观和用户体验
前端
vue react angular.js
# 前后端分离网站:路飞
to B:(CMDB)
前后端不分离
讲究用途和功能齐全
前端
bootstrap、layui
# 前后端不分离网站:很丑的基本都是

11.前端框架使用layui

https://www.layui.com/demo/admin.html

1.使用CDN模式
https://www.bootcdn.cn/ 2.直接下载文档
使用文档中的css和js
layui/layui.all.js
# <script src="/static/layui/layui.all.js"></script>
layui/css/layui.css
# <link rel="stylesheet" href="/static/layui/css/layui.css">

12. Xadmin使用(后台管理)

  Django-xadmin介绍

    Django是python的重量级web框架,写得少,做得多,非常适合后端开发,它很大的一个亮点是,自带后台管理模块,但它自带的后台管理有点丑,而Xadmin是基于bootstrap开发的一套后台管理框架,界面非常美观,只需几步就可以替换自带的Django_admin
xadmin有很多小bug,使用的时候最好心理准备,可能需要你自己修改源码
基于bootstrap的后台管理
vue-element-admin:最新使用的
基于vue开发的非常酷炫的后台管理

安装步骤:

1.在python 2.x版本中安装方法
pip install xadmin 2.xadmin在python3.6.x时代的安装方法,需要以下插件
pip3 install django-import-export
pip3 install django-reversion
pip3 install django-formtools==2.1
pip3 install future
pip3 install httplib2
pip3 install six
pip3 install django-crispy-forms bootstrap高级模板:https://wrapbootstrap.com/

3.下载xadmin
  https://github.com/sshwsfc/xadmin   只需要zip文件中的xadmin目录

4.在django中的根目录下创建extra_apps(如果不存在此文件夹则创建, 然后鼠标右键extra_app 随后 mark as sources root,用来创建第三方应用
Python Package是带init文件的,跟普通Package不同)
创建完extra_apps,需要在settings中配置一下extra_apps。设置为可搜索的路径
# 1.创建完extra_apps,需要在settings中配置一下extra_apps。设置为可搜索的路径

import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps')) # 把extra_apps文件夹添加到搜索目录中 # 2.配置到 INSTALLED_APPS
## 显示中文
LANGUAGE_CODE = 'zh-hans' # TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
# xadmin后台界面显示中文
LANGUAGE_CODE = 'zh-hans'

# 新增
INSTALLED_APPS = [
'xadmin',
'crispy_forms', # 注意crispy_forms之间是下划线隔开,不是横线
] # 3. urls.py中把admin换成xadmin
import xadmin
from django.conf.urls import url
from django.contrib import admin urlpatterns = [
# url('admin/', admin.site.urls),
url(r'^xadmin/', xadmin.site.urls),
] # 4.迁移文件:迁移完成之后数据库会多几张xadmin_开头的表
python3 manage.py makemigrations
python3 manage.py migrate """因为版本的原因,有一些报错慢慢解决""" #5.pycharm创建superuser 用户
python3 manage.py 访问:http://127.0.0.1:8000/xadmin/
Xadmin使用

#1.需要在后台管理app中创建adminx.py文件
import xadmin
from repository import models
from xadmin import views class UserProfileAdmin(object):
# 1.显示的字段名称
list_display = ['id','name' ,'email','phone','mobile'] # 2.搜索时可输入的字段内容
search_fields = ['id', 'name', 'email', 'phone'] # 3.点击id可进入详细界面进行编辑(默认的)
list_display_links = ('id',) # 4.可编辑的列名
list_editable = ['name' ,'email','phone','mobile']
# list_filter = ['name' ,'email','phone','mobile'] # 5.每页显示多少条
list_per_page = 20 #6.根据id排序
ordering = ('id',) 
 
# 7.设置只读字段 
readonly_fields = ('id',) #8.显示本条数据的所有信息
show_detail_fields = ['asset_name'] # data_charts = {
# "user_count": {'title': u"用户分布", "x-field": "name", "y-field": ("id",),},
# # "avg_count": {'title': u"Avg Report", "x-field": "date", "y-field": ('avg_count',), "order": ('date',)}
# } xadmin.site.register(models.UserProfile,UserProfileAdmin) # 2.是否设置书签名
默认是开启书签的
show_bookmarks 属性: 设置是否开启书签功能, 默认为 True
list_bookmarks 属性: 设置默认的书签. 用户可以在列表页面添加自己的书签, 你也可以实现设定好一些书签 list_bookmarks = [{
"title": "存在邮箱", # 书签的名称, 显示在书签菜单中
"query": {"user_email__contains": '@'}, 过滤参数, 是标准的 queryset 过滤
"order": ("-user_name",), # 排序参数
"cols": ('user_name', 'user_email', 'user_mobile'),# 显示的列
}] # 3.数据导出
"""
如果想要导出Excel数据,需要安装xlwt。 默认情况下,xadmin会提供Excel,CSV,XML,json四种格式的数据导出,可以通过设置OptionClass的list_export属性来指定使用哪些导出格式(四种格式分别用xls,csv,xml,json表示)或是将list_export设置为None来禁用数据导出功能
"""
list_export = ('xls', 'xml', 'json')
list_export_fields = ('id', 'name', 'title') # 4. 设置全局配置
#如下的代码可以在任何的app中
import xadmin
from repository import models from xadmin import views
# 全局修改,固定写法
class GlobalSettings(object):
# 修改title
site_title = 'xxx后台管理界面'
# 修改footer
site_footer = 'xxx的公司'
# 收起菜单
menu_style = 'accordion' # 设置 models图标
# https://v3.bootcss.com/components/
global_search_models = [models.Disk, models.Server]
global_models_icon = {
# Server: "glyphicon glyphicon-tree-conifer", Pool: "fa fa-cloud"
models.Server: "fa fa-linux",
models.Disk: "fa fa-cloud"
} # 将title和footer信息进行注册
xadmin.site.register(views.CommAdminView,GlobalSettings) # 创建xadmin的最基本管理器配置,并与view绑定
class BaseSetting(object):
# 开启主题功能
enable_themes = True
use_bootswatch = True # 将基本配置管理与view绑定
xadmin.site.register(views.BaseAdminView,BaseSetting) #5.图表显示(不好看不用)
data_charts = {
"host_idc_counts": {
'title': '机房统计',
'x-field': "idc",
'y-field': ("idc",),
'option': {
"series": {"bars": {"align": "center", "barWidth": 0.3, "show": True}},
"xaxis": {"aggregate": "count", "mode": "categories"}
}
}

xadmin使用

13. 数据可视化

highcharts
echarts
antv

CMDB开发(三)的更多相关文章

  1. Python CMDB开发

    Python CMDB开发   运维自动化路线: cmdb的开发需要包含三部分功能: 采集硬件数据 API 页面管理 执行流程:服务器的客户端采集硬件数据,然后将硬件信息发送到API,API负责将获取 ...

  2. App开发三种模式

    APP开发三种模式 现在App开发的模式包含以下三种: Native App 原生开发AppWeb App 网页AppHybrid App 混合原生和Web技术开发的App 详细介绍: http:// ...

  3. iOS开发三步搞定百度推送

    iOS开发三步搞定百度推送   百度推送很简单,准备工作:在百度云推送平台注册应用,上传证书. 步骤一: 百度云推送平台 http://push.baidu.com/sdk/push_client_s ...

  4. 基于Spring MVC的Web应用开发(三) - Resources

    基于Spring MVC的Web应用开发(3) - Resources 上一篇介绍了在基于Spring MVC的Web项目中加入日志,本文介绍Spring MVC如何处理资源文件. 注意到本项目的we ...

  5. Java Web高性能开发(三)

    今日要闻: Clarifai:可识别视频中物体 最近几年,得益于深度学习技术的发展,谷歌和Facebook等企业的研究人员在图形识别软件领域取得了重大突破.现在,一家名为Clarifai的创业公司则提 ...

  6. C#的百度地图开发(三)依据坐标获取位置、商圈及周边信息

    原文:C#的百度地图开发(三)依据坐标获取位置.商圈及周边信息 我们得到了百度坐标,现在依据这一坐标来获取相应的信息.下面是相应的代码 public class BaiduMap { /// < ...

  7. Qt计算器开发(三):执行效果及项目总结

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/guodongxiaren/article/details/26046543 执行效果 project ...

  8. GitHub 多人协作开发 三种方式:

    GitHub 多人协作开发 三种方式: 一.Fork 方式 网上介绍比较多的方式(比较大型的开源项目,比如cocos2d-x) 开发者 fork 自己生成一个独立的分支,跟主分支完全独立,pull代码 ...

  9. 从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件

    标题:从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/112 ...

  10. Python服务器开发三:Socket

    Python服务器开发三:Socket   socket是操作系统中I/O的延续,它可以使进程和机器之间的通信成为可能.socket可以看成一个标准的文件描述符.不同的是文件需要用open()函数打开 ...

随机推荐

  1. 记录-Vue.js模板编译过程揭秘:从模板字符串到渲染函数

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 Vue.js是一个基于组件化和响应式数据流的前端框架.当我们在Vue中编写模板代码时,它会被Vue编译器处理并转换为可被浏览器解析的Jav ...

  2. Chrome浏览器:The request client is not a secure context and the resource is in more-private address ...

    1.概述 新版的chrome浏览器会校验发起端的域名和访问资源的域名直接的关系,如果客户端发起域名比访问资源所在的域名更public(开放),会导致The request client is not ...

  3. 【已解决】Hadoop未知的主机名master

  4. 强烈推荐:2024 年12款 Visual Studio 亲测、好用、优秀的工具,AI插件等

    工具类扩展 1. ILSpy 2022 (免费) ILSpy 是 ILSpy 开源反编译器的 Visual Studio 扩展. 是一款开源.免费的.且适用于.NET平台反编译[C#语言编写的程序和库 ...

  5. rsync 运维利器,同步工具

    NAME rsync - faster, flexible replacement for rcp SYNOPSIS rsync [OPTION]... SRC [SRC]... DEST rsync ...

  6. 批量拉取/git pull 指定文件夹下面所有 Git 项目的最新代码

    背景 因为工作需要,当前所负责的项目较多:但是人力紧缺,其中绝大部分项目平时也不会去跟进迭代.所以经常需要批量拉取最新的代码查看最新的改动. 解决方案 一键批量拉取指定文件夹下所有 Git 项目的最新 ...

  7. 基于文件语义实现S3接口语义的注意事项

    本文标题中提到的文件语义,指的是POSIX规范. S3指的是AWS提供的对象存储服务以及相关接口.为方便描述,下文中以对象语义替代S3接口语义. 文件语义和对象语义存在比较多的差异. 对象语义不支持文 ...

  8. Docker 12 Dockerfile

    简介 Dockerfile 是用来构建 Docker 镜像的文件,可以理解为命令参数脚本. Dockerfile 是面向开发的,想要打包项目,就要编写 Dockerfile 文件. 由于 Docker ...

  9. Data Technology时代,如何成为一名优秀的电商数据分析师?

    又是一年春招季,你最近有为找工作或换工作而犯愁吗?现在已经进入春招的"金三银四"决赛圈了,再不好好准备真的是黄花菜都要凉了.那么如何才能在"岗少人多".&quo ...

  10. 前端vue监听activeMQ消息后端推送消息--实战

    需求 : 工厂员工完成某道工序后,需要将消息推送给 检查人员 也可以使用 WebSockets ,前端更容易实现 思路: 使用activeMQ推送消息,前端实时接收消息 实现 : 1.基于spring ...