数据专栏

智能大数据搬运工,你想要的我们都有

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

「深度学习福利」大神带你进阶工程师,立即查看>>>
运维工程师—李晨星
一、虚拟化
1. 什么是虚拟化 虚拟化,是指通过虚拟化技术模拟计算机的硬件,虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率。 虚拟化使用软件的方法重新定义划分IT资源,可以实现IT资源的动态分配、灵活调度、跨域共享,提高IT资源利用率,使IT资源能够真正成为社会基础设施,服务于各行各业中灵活多变的应用需求。
2. 虚拟化软件的差别
Linux虚拟化软件: qemu:软件纯模拟全虚拟化软件,特别慢!AIX,兼容性好! Xen:性能特别好,需要使用专门修改之后的内核,兼容性差! KVM:虚拟机,它有硬件支持CPU,基于Linux内核,而且不需要使用专门的内核!性能较好,兼容较好 VMware:图形界面,虚拟机管理管理软件,同时可运行多个操作系统在主系统的平台上,可以进行虚拟的分区、配置而不影响真实硬盘的数据,可通过网卡将虚拟机连为局域网,极其方便。 virtual box:号称最强的免费虚拟机软件,Oracle已收购,非常小。使用上和VMware差不多,有点耗CPU。
二、XenServer服务器虚拟化平台
1. 首先从Xen开始说起
Xen 体系的架构
Xen 的 VMM ( Xen Hypervisor ) 位于操作系统和硬件之间,负责为上层运行的操作系统内核提供虚拟化的硬件资源,负责管理和分配这些资源,并确保上层虚拟机(称为域 Domain)之间的相互隔离。Xen采用混合模式,因而设定了一个特权域用以辅助Xen管理其他的域,并提供虚拟的资源服务,该特权域称为Domain0,而其余的域则称为Domain U。 其中最特殊的domain被称为Domain 0或VM 0,这是一个控制Domain,简称为Dom0,如上图左侧。 Domain 0除去包含了对应系统设备的所有驱动程序外,还有用来管理基于Xen系统的一个控制栈及多种系统服务。 通过Domain 0分解,可以将某些Domain 0中的服务及设备驱动拆出来,放在某专有虚拟机中运行,这需要一些特殊配置。
因此Xen就包含了三个部分: Xen Hypervisor: 直接运行于硬件之上是Xen客户操作系统与硬件资源之间的访问接口。直接在硬件上运行,负责管理CPU、内存和中断。它是引导装载程序退出后运行的第一个程序。管理程序本身不处理I/O功能,如网络和存储。 Domain 0: 别名Dom0,这是一个特殊的虚拟机,运行在Xen管理程序之上,具有直接访问硬件和管理其他客户操作系统的特权的客户操作系统。没有Dom0,Xen hypervisor就不能使用。 Domain U: 运行在Xen管理程序之上的普通客户操作系统或业务操作系统,不能直接访问硬件资源(如:内存,硬盘等),但可以独立并行的存在多个。 Xen还提供了图形化管理工具 XenCenter 来管理资源。通过XenCenter 可以完成所有的配置操作,在实施中大部分配置操作都会通过该管理工具实现。
2. XenServer介绍 XenServer 是一个由 Citrix 发起和管理的完整服务器虚拟化开源平台项目。 已同时针对 Windows 和 Linux 虚拟服务器进行了优化。 直接在服务器硬件上运行而不需要底层操作系统,因而是一种高效且可扩展的系统。 该项目开发的开源软件实现了虚拟化的多种功能,允许在硬件设备上安全地运行多个操作系统和应用程序,完成硬件整合和自动化。 工作方式是从物理机中提取元素(例如硬盘驱动器、资源和端口),然后将其分配给物理机上运行的虚拟机 VM 的运行方式与物理机十分相似,并且包含自己的虚拟(基于软件)CPU、RAM、硬盘和网络接口卡 (NIC)。 将静态、复杂的IT环境转变为更加动态、易于管理的虚拟数据中心,有效地降低IT资源成本,提供的先进管理功能,实现虚拟数据中心的集成和自动化,简化服务器和应用程序的管理。
XenServer的优点: 使用 XenServer 时,可以通过以下方式降低成本: 将多个 VM 合并到物理服务器上; 减少需要管理的单独磁盘映像的数量; 允许与现有网络和存储基础结构方便地集成。 使用 XenServer 时,可以通过以下方式提高灵活性。 允许使用 XenMotion 在 XenServer 主机之间实时迁移 VM,在确保零停机时间的情况下安排维护工作。 使用高可用×××配置相应策略(当一个 XenServer 主机发生故障时在另一个主机上重新启动 VM),从而提高 VM 的可用性,将一个 VM 映像用于一系列的部署基础结构中,从而提高 VM 映像的可移植性
XenServer 体系的架构:
Citrix官网
Xen hypervisor直接运行在物理硬件上,负责处理CPU、内存、定时器和中断等相关任务。系统在完成引导加载程序后,Xen hypervisor首先启动。
XenServer 包含: Xen 虚拟机管理程序:
此虚拟机管理程序是软件的基础抽象层。此虚拟机管理程序负责底层任务,
例如 CPU 调度,并且负责常驻 VM 的内存隔离。此虚拟机管理程序从 VM 的硬件提取。此虚拟机管
理程序无法识别网络连接、外部存储设备、视频等。 控制域:
也称作“Domain0”或“dom0”,控制域是一个安全的特权 Linux VM(基于 CentOS
v5.10 发行版),运行 XenServer 管理 toolstack。除了提供 XenServer 管理功能之外,控制域还
运行驱动程序堆栈,提供对物理设备的用户创建虚拟机 (VM) 访问。 管理 toolstack:
也称作 xapi,该软件 toolstack 可以控制 VM 生命周期操作、主机和 VM 网络连
接、VM 存储、用户身份验证,并允许管理 XenServer 资源池。xapi 提供公开记录的 XenAPI 管理接口,以供管理 VM 和资源池的所有工具使用。 VM 虚拟机
用于将受欢迎操作系统安装为 VM。也就是Xen当中的Domain U。
3. Xen与XenServer的区别 图中绿色框起来的部分就是Xen,红色框起来的部分就是XenServer Xen就好比是汽车的发动机,而XenServer就是在Xen这台发动机的基础之上,给它安装上别的汽车零件,组装成一台可以在路上跑的汽车。
4. XenServer主机系统要求
XenServer的硬件兼容性列表_官网文档 XenServer 需要至少两台单独的 x86 物理计算机:一台作为 XenServer 主机,另一台运行 XenCenter 应用程序。 XenServer 主机计算机专用于运行托管 VM 的 XenServer,而不用于运行其他应用程序。 不支持直接在 XenServer 主机上(即,安装在 dom0 控制域中)安装任何第三方软件,但作为 增补包提供并且由 Citrix 明确认可的除外。 运行 XenCenter 的计算机可以是满足硬件要求的任何通用 Windows 计算机,也可用于运行其 他应用程序。


三、XenServer 安装步骤
官方文档
1. 版本选择 XenServer7.6发布于2018年9月5日,XenServer提供免费的开源版本;同时也保持了两个商用版本 Standard 和 Enterprise。 Standard Edition 是入门级商用产品,如果希望使用强大的高性能虚拟化平台,但不需要 Enterprise Edition 提供的高级功能,而同时仍希望获得全面的 Citrix 支持和维护保障,本版本提供的一系列功能可以满足此类客户的需求。 Enterprise Edition 是全功能高级版本,已针对服务器、桌面和云工作负载进行了优化。
这里暂时安装免费版
XenServer7.6官方安装文档-PDF
enServer 7.6免费版镜像下载地址;下载之前需要先注册一个Citrix账号
2. 主机系统要求 一个或多个64位x86 CPU,主频不低于1.5GHz,支持Intel VT或AMD-V 最低2GB内存 最低磁盘空间46GB 100Mbit/s或更快的网卡
测试环境下没有多余的服务器,所以XenServer的安装将会部署到VMware虚拟机中。
3. 新建虚拟机

因为没有Xen的选项,选择ESXI就可以了

磁盘容量建议给大一些200G+
4. XenServer引导安装
F2可以选择高级安装。正常情况下不需要用到高级安装,直接回车跳转到下一步 选择US→OK
继续点击OK
选择 Accept EULA
选定磁盘用于虚拟机存储,空格键选定磁盘及Enable thin provisioning后 OK继续
选择Local Media
选择 Skip verification , 跳过安装介质的检测 输入XenServer的root登陆密码 这里网络环境是桥接;所以直接选择默认; 如果定义管理网络IP地址,需要选择手动配置IP,输入IP、 掩码、 网关; 如果环境有多张网卡,则在此页面前有一个选择一个网卡作为管理网口的选项
配置主机名和DNS
选择 Asia(亚洲) 选择Shanghai 上海 选择Manual timeenty(手动输入时间) 也可以选择NTP时间同步,我们可以使用阿里云的NTP服务器地址 ntp1.aliyun.com
开始安装,点击Install XenServer——回车
安装过程中..
取消安装附加包 出现下面窗口,填入当前的正确日期时间
点击OK后自动重启
重启中
XenServer 7.6 启动完成,完成安装
XenServer 7.6 的界面管理翻译
5. 管理XenServer的方式
》XenServer 命令行界面 (CLI) 可以使用基于 Linux 的 xe 命令来管理 XenServer 也可以使用Xshell连接XenServer的命令行
》基于 Windows 的图形用户界面—XenCenter
三、客户端管理软件—XenCenter汉化版的安装 浏览器访问IP地址 http://10.0.0.72 点击XenCenter installer,下载XenCenter安装包,这里不推荐下载,可下载中文版 Xencenter7.6的汉化版 网盘提取码: t4ht XenCenter官方下载链接
连接虚拟机
四、配置XenServer的YUM源 vi /etc/yum.repos.d/CentOS-Base.repo # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # update status of each mirror to pick mirrors that are updated to and # geographically close to the client. You should use this for CentOS updates # unless you are manually picking other mirrors. # # If the mirrorlist= does not work for you, as a fall back you can try the # remarked out baseurl= line instead. # # [base] name=CentOS-$releasever - Base #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra baseurl=http://mirror.centos.org/centos/7/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #released updates [updates] name=CentOS-$releasever - Updates #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra baseurl=http://mirror.centos.org/centos/7/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #additional packages that may be useful [extras] name=CentOS-$releasever - Extras #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra baseurl=http://mirror.centos.org/centos/7/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #additional packages that extend functionality of existing packages [centosplus] name=CentOS-$releasever - Plus #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra baseurl=http://mirror.centos.org/centos/7/centosplus/$basearch/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 ===================================================== yum repolist all
五、XenServer安装Centos8 虚拟机
1. 安装规划 * 使用XenCenter创建Centos8虚拟机,安装Centos8系统,生成快照,并通过快照安装Centos8虚拟机 * 下载Centos8安装的ISO文件 * 使用本地的ISO作为储存库(SR),将Centos8的ISO文件上传到SR * 新建虚拟机并安装Centos8系统 * 给虚拟机作初始化配置并生成快照 * 根据快照快速安装Centos8虚拟机 * 安装过程程需要使用到Xshell和Xftp工具,需要提前安装好
CentOS8镜像下载地址
2. 安装步骤规划 * 使用Xshell连接XenServer服务器 * 创建ISO库和本地存储库,并将centos8的ISO文件上传到SR * 打开Xftp,将Centos8的ISO文件上传至/boot-iso目录下 * 进入XenCenter,连接上XenServer后刷新一下,选中新增加的boot-iso,选择Storage选项卡,点击Rescan,发现centos8的ISO文件 在虚拟环境中安装虚拟机需要用到ISO包,且虚拟机创建后需要一定空间来存储。这就分别需要用到ISO库和本地存储库
3. 创建ISO镜像库
XenServer 定义了一个名为存储库(SR) 的容器来描述存储虚拟磁盘映像 (VDI) 的特定存储目标。VDI是包含虚拟磁盘内容的磁盘抽象。 #新建iso存放目录 [root@XenServer7 ~]# mkdir /boot-iso/ #xe命令创建sr存储库 [root@XenServer7 ~]# xe sr-create name-label=boot-iso type=iso device-config:location=/boot-iso device-config:legacy_mode=true content-type=iso [root@XenServer7 ~]# cd /boot-iso/
使用传输工具将镜像传送到/boot-iso/目录下
3.1 创建windows共享的ISO库

在XenCenter上添加SR库
添加成功
4. 新建虚拟机,按步骤配置 * 选择安装的操作系统 * 给vm取一个名字 * 选择iso镜像 * Home Server设置 * CPU和内存设置 * GPU设置 * 存储设置 * 网路设置 * 完成
5. VM虚拟机创建完成
CentOS8的部署过程链接
6. 使用Xshell连上Centos8-node1虚拟机,进行基本的设置与生成快照
7. 利用快照文件快速的添加新的VM * 选中快照右键选择“New VM from Snapshot” * 参照前面新建VM过程,一直Next至完成,内存和磁盘大小最好保持不变
8. 安装 XenServer Tools 创建新的虚拟机开机后,在常规的虚拟化状态里会显示未安装XenServer Tools 这个XenServer Tools可以起到一个 虚拟机的优化的作用 ,如果不安装,虚拟机的优化会受到很大的影响不仅仅windows可以按照XenServer Tools,在Linux上也可以安装。
点击框中的提示
XenCenter管理工具会自动将“XenServer Tools”光盘映像插入到该虚拟机的光驱中,接下来就是SSH方式登录到该虚拟机,执行剩余的安装步骤。 操作步骤如下: [root@centos7-node1 ~]# cd /mnt/ [root@centos7-node1 mnt]# mkdir xenserver-tools [root@centos7-node1 mnt]# mount /dev/cdrom /mnt/xenserver-tools/ mount: /dev/sr0 写保护,将以只读方式挂载 [root@centos7-node1 mnt]# cd xenserver-tools/Linux/ [root@centos7-node1 Linux]# ./install.sh Detected `CentOS Linux release 7.6.1810 (Core) ' (centos version 7). The following changes will be made to this Virtual Machine: * update arp_notify sysctl. * packages to be installed/upgraded: - xe-guest-utilities-7.10.0-1.x86_64.rpm - xe-guest-utilities-xenstore-7.10.0-1.x86_64.rpm Continue? [y/n] y 准备中... ################################# [100%] 正在升级/安装... 1:xe-guest-utilities-xenstore-7.10.################################# [ 50%] 2:xe-guest-utilities-7.10.0-1 ################################# [100%] You should now reboot this Virtual Machine. [root@centos7-node1 Linux]# [root@centos7-node1 Linux]# reboot #需要重启
记得拍摄快照
六、VM虚拟机的复制、导入导出
复制 用于生产使用,建议进行完整复制 用于测试使用,建议进行快速克隆 将每台虚拟机的存储名称都修改一下
导出 可以把虚拟机拷贝成文件,然后拷贝到别处,在另外一台虚拟机上把它导入进去。
导入 可以使用不同的虚拟化平台的虚拟机可以互相使用
七、虚拟机模板创建与使用
创建模板
使用模板 创建完成
八、管理和配置存储
1. 本地存储
1.1 如果虚拟机的内存不够了,可以在存储中添加新的硬盘
·· fdisk /dev/xvdb 创建分区 mkfs.ext3 /dev/xvdb 格式化分区 mount /dev/xvdb /mnt/ 挂载分区 [root@centos7-node1 ~]# df -h /dev/xvdb 4.8G 11M 4.6G 1% /mnt
1.2 磁盘的分离与连接
需要提前卸载掉磁盘后再进行分离
2. 配置网络存储
2.1 下载starwind工具
starwind安装手册 starwind下载地址 这里是免费版本,选择第二项 选择第一项Starwind "Browse": 选择下载的license文件,文件名称扩展名为".swk" 安装完成后启动管理控制台
2.2 创建管理控制台
2.3 回到XenCenter上创建存储库
3. NFS 存储
1. 搭建nfs服务器
nfs搭建步骤 #下载软件 yum install -y nfs-utils rpcbind #启动rpcbind服务查看rpc服务注册信息 systemctl start rpcbind.service rpcinfo -p #启动nfs服务并查看注册信息 systemctl restart nfs rpcinfo -p #添加nfs配置文件 vim /etc/exports #share /data /data 10.0.0.22/24(rw) #创建共享的目录并修改权限 mkdir /data chown nfsnobody.nfsnobody /data systemctl reload nfs #检查 挂载 showmount -e mount -t nfs 10.0.0.81:/data /mnt
2. 创建存储库并应用
九、管理和配置网络
1. 准备网络环境
首先给XenServer服务器再添加俩块网卡进行测试
在XenCenter上重新扫描
1. 外部网络
将第一台虚拟机的网卡修改为Vlan2
将第二台虚拟机的网卡修改为Vlan3 他们的网络互相不通,需要配置Trank
2. 单服务器专用网络
只有这一台服务器里的虚拟机之间可以通讯,不可以与外部通讯。 如果需要多个网络环境,还可以创建多个单服务器专用网络进行使用。
可根据网络使用需求创建多个
将俩台虚拟机网络修改为 "单服务器专用网络 (1)"
进行单服务器专用网络的测试
将第一台虚拟机修改为 网卡0,让其访问外网
3. 绑定网络
就是把俩块网卡绑定在一起,主要的目的是为了提高冗余性和负载均衡。 如果一块网卡坏掉,另外一块网卡可以承担全部的流量,有主动和被动模式俩种。
将俩台虚拟机网卡都修改为 绑定1+2
查看IP地址 检查网络
4. 跨服务器专用网络
创建资源池以后可以进行操作
5. SR-IOV网络
XenServer的SR-IOV技术 在大规模和高并发的情况下,是无法满足虚拟机的性能需求的。比如在XenServe上面部署邮件系统进行大规模并发压力测试的时候,就会发现,网络IO是一个瓶颈。 所以基于这样的需求,我们可以在XenServer上面使用基于硬件的IO虚拟化SR-IOV技术,提高我们Exchange虚拟机系统的网络IO的性能。 SR-IOV(Single Root I/O Virtualization)可允许Windows操作系统和微软的Hyper-V或VMware的ESXi等hypervisor对服务器的磁盘I/O设备,如现在SR-IOV对网卡设备一样进行封装,管理甚至共享。
十、管理许可证
1. 免费许可证现在已经无法激活
需要购买思杰官方的XenServer高级版,企业版,铂金版许可证 如果是商业版本,需要创建许可证服务器,把许可证导入到许可证服务器,然后对XenServer进行授权。许可证服务器可以是基于Linux的,也可以是基于Windows的。
思杰官方购买链接
具体操作流程可网上搜索 导入Linux许可证服务器 分配许可证 在windows中安装许可证服务器
十、资源池管理 资源池最大的好处就是可以负载均衡,高可靠性能。资源池通常使用网络存储。 有了资源池,虚拟机之间可以进行迁移,如果其中一台需要维护或者发生故障,那么虚拟机可以迁移到另外一台XenServer上。 因使用免费版本的软件,一些功能未开放,一些测试暂时不能往下继续,环境允许以后会及时进行文档补充
1. 创建资源池
在资源池中添加主机 在资源池中迁移虚拟机 跨服务器专用网络
十一、使用XenConvert把实体计算机转为虚拟机
XenConver的转换 Citrix XenServer提供免费的P2V转换工具叫Citrix XenConvert,可以实现P2V、V2V转换。 其实Citrix还有个工具Citrix XenServer Conversion Manager(Citrix XenServer转换管理器) 可以转换多达数百个VMware vSphere的虚拟机到Citrix XenServer平台上。这样可以节省时间和存储,直接将虚拟机转换到XenServer无人值守。 使用Citrix XenConvert是从一个单一的服务器或台式机的物理机上运行Windows的XenServer的开放虚拟化格式,或在虚拟硬盘(VHD)格式的虚拟磁盘转换成.vhd/.ova/.ovf等格式。通过XenCenter可以导入到XenServer的一个虚拟设备和虚拟磁盘。 XenConvert可以将服务器或桌面工作负载从包含任何客户机操作系统(包括Windows和Linux)的脱机虚拟机或磁盘转换为XenServer虚拟机。
十二、XenServer的高可用和负载均衡
因使用免费版本的软件,一些功能未开放,一些测试暂时不能往下继续,环境允许以后会及时进行文档补充
高可用性 一定要使用共享存储 一定要有资源池 一定要配置高可靠性 会造成业务的短时间中断
负载均衡
十三、配置VM保护策略和 vApp
1. 配置VM保护策略
2. vApp 虚拟机如果有很多台,那么之间的虚拟机肯定会有互相依赖 比如一台web服务器要连接另一台的数据库,如果数据库没有启动起来,那么web服务器会连接不成功,因此需要先启动数据库的虚拟机,然后再开web虚拟机。这时就需要创建一组vApp
十四、XenServer的更新
等待更新完成
十五、XenServer的管理命令 #列出模块,找到对应存储的UUID,其中PBD(物理块设备,physical block device) xe pbd-list xe pbd-unplug uuid=uuid of PBD #列出存储的UUID,找到对应存储的UUID xe sr-list #删除本地存储连接 xe sr-destroy uuid=uuid of SR 一、监控检查类 xentop-查看XenServer与VM的资源使用情况 xsconsole-进入XenServer管理面板(查看网卡,IP,系统版本,系统时间,硬件信息等) xe task-list-查看XenServer临时任务进程 service --status-all-查看所有服务运行状态 二、通用监控检查命令 pvs -- 查看物理卷 pvscan vgdisplay lvs -- 查看逻辑卷 lvscan lvdisplay rm -rf 目录/文件 -- 强制删除目录/文件 fdisk -l -- 查看Linux硬盘信息(名称与分区等) df -hal -- 查看Linux系统信息(系统空间,挂载信息等) du -hcs 目录/文件 -- 查看该目录/文件的大小 du -hcs /var/log/ -- 查看日志文件大小 top -- 查看XenServer系统进程与负载情况 vi /etc/rc.local -- 查看系统启动任务 crontab -e -- 查看定时执行的任务 history -- 查看最近使用的命令 clear -- 清屏 curl 域名 -- 访问域名 三、系统操作类 service xapi restart-重启XAPI服务(负载过高时慎用) xe-toolstack-restart-重启XenServer所有服务(负载过高时慎用) reboot-重启服务器 mount 逻辑卷 目录-将逻辑卷挂载到该目录(挂载后df -hal可查看) umount 逻辑卷 目录-反挂载 lvremove-移除逻辑卷 四、XE SR操作类 xe sr-list-显示所有物理存储(SR)信息 xe sr-list uuid="UUID" - 匹配SR的UUID显示SR信息 xe sr-list name-label="SR名称" - 匹配SR名称显示SR信息 1.删除SR操作(数据会丢失) xe pbd-list sr-uuid="SR-UUID" -- 匹配SR的UUID找出对应的物理连接(PBD)信息 xe pbd-unplug uuid="PBD-UUID" -- 匹配PBD的UUID删除对应的PBD xe sr-forget uuid="SR-UUID" -- 匹配SR的UUID遗忘对应的SR 2.创建物理存储(成功后原数据丢失) xe sr-create name-label="自定义名称" shared=false device-config-device=/dev/sdb(设备名) type=lvm 五、XE VM操作类 xe vm-start name-label="VM名称" -- 匹配VM名称执行VM开机 xe vm-reboot name-label="VM名称" -- 匹配VM名称执行VM重启 xe vm-shutdown name-label="VM名称" -- 匹配VM名称执行VM关机 xe vm-shutdown uuid="UUID" -- 匹配VM的UUID执行VM关机,以下同理 xe vm-start uuid="UUID" xe vm-reboot uuid="UUID" xe vm-list -- 显示所有VM信息 xe vm-list name-label="VM名称" -- 匹配名称显示VM信息 xe vm-list uuid="UUID" -- 匹配uuid显示VM信息 xe vdi-list -- 显示所有虚拟硬盘(VDI)信息 xe vdi-list vm-uuid="VM-UUID" -- 匹配VM的UUID显示VDI信息 xe vdi-list uuid="UUID" -- 匹配VDI的UUID显示VDI信息 xe vdi-list name-label="VDI名称" -- 匹配VDI名称显示VDI信息 xe vdi-forgrt uuid="UUID" -- 匹配VDI的UUID遗忘该VDI信息(srcan可找回) 六、端口映射类 iptables -t nat -nvL -- 查看端口映射信息表 1.手动添加端口映射(重启后会丢失) iptables -t nat -A PREROUTING -i eth0(网卡名) -p tcp -d 公网IP --dport 80(端口) -j DNAT --to-destination 映射IP:80 2.映射出口规则(重启后会丢失) iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 3.XenSystem_NAT_Server(nginx) /etc/init.d/networking restart -- 重启网卡 vi /etc/resolv.conf -- 修改DNS vi /etc/network/interfaces -- 查看NAT
系统运维
2019-12-02 18:56:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
Linux :CentOS7 卸载mysql
方法一、
1. 查看 mysql 安装
rpm -qa|grep -i mysql
2. 卸载前关闭 mysql 服务
rpm -ev --nodeps mysql-community-release-el7-5.noarch
rpm -ev --nodeps mysql-community-common-5.6.38-2.el7.x86_64
rpm -ev --nodeps mysql-community-client-5.6.38-2.el7.x86_64
rpm -ev --nodeps mysql-community-libs-5.6.38-2.el7.x86_64
rpm -ev --nodeps community-server-5.6.38-2.el7.x86_64
执行完命令之后 再次执行 rpm-qa|grep -i mysql 会发现已经卸载完成。

方法二、
执行命令
find / -name mysql
把查找出的目录删除
rm -rf 上面查出的文件夹
etc/my.cnf 如果存在的话手动删除,这样 mysql 就卸载完成了。
[root @node1 ~]# rm -rf /etc/my.cnf
[root @node1 ~]# rm -rf /var/lib/mysql/
Buy me a cup of coffee :)
系统运维
2019-12-02 17:06:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
、卸载
[root @node1 ~]# rpm -qa|grep mariadb
mariadb-5.5.56-2.el7.x86_64
mariadb-libs-5.5.56-2.el7.x86_64
mariadb-server-5.5.56-2.el7.x86_64
[root @node1 ~]#
[root @node1 ~]# yum remove mariadb
...
Removed:
mariadb.x86_64 1:5.5.56-2.el7

Dependency Removed:
mariadb-server.x86_64 1:5.5.56-2.el7

Complete!
2、删除遗留目录
[root @node1 ~]#/etc/my.cnf
[root @node1 ~]# ll /var/lib/mysql/
total 28700
-rw-rw---- 1 mysql mysql 16384 May 5 10:31 aria_log.00000001
-rw-rw---- 1 mysql mysql 52 May 5 10:31 aria_log_control
-rw-rw---- 1 mysql mysql 18874368 May 5 10:31 ibdata1
-rw-rw---- 1 mysql mysql 5242880 May 5 10:31 ib_logfile0
-rw-rw---- 1 mysql mysql 5242880 Oct 6 2017 ib_logfile1
drwx------ 2 mysql mysql 4096 Oct 6 2017 mysql
drwx------ 2 mysql mysql 4096 Oct 6 2017 performance_schema
[root@node1 ~]# rm -rf /etc/my.cnf
[root@node1 ~]# rm -rf /var/lib/mysql/
3、重新安装
[root@node1 ~]# yum install -y mariadb mariadb-server
[root@node1 ~]# systemctl start mariadb
[root@node1 ~]# systemctl enable mariadb
[root@node1 ~]# mysql_secure_installation
Buy me a cup of coffee :)
系统运维
2019-12-02 16:56:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
vim 编辑命令
按ESC键 跳到命令模式,然后:
:w - 保存文件,不退出 vim
:w file -将修改另外保存到 file 中,不退出 vim
:w! -强制保存,不退出 vim
:wq -保存文件,退出 vim
:wq! -强制保存文件,退出 vim
:q -不保存文件,退出 vim
:q! -不保存文件,强制退出 vim
:e! -放弃所有修改,从上次保存文件开始再编辑

Buy me a cup of coffee :)
系统运维
2019-12-02 15:35:00
「深度学习福利」大神带你进阶工程师,立即查看>>> 在开始-> 运行命令 栏中输入 gpedit.msc   在组策略中依次打开“计算机配置→策略→管理模板→Windows 组件→远程桌面服务→远程桌面会话主机→连接”中,选择“限制连接数量”进行配置。
Buy me a cup of coffee :)
系统运维
2019-12-02 14:56:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
元数据是自动化运维的基础,对元数据的管理和查询贯穿整个运维的生命周期。我们从一个元数据的使用场景开始:
双十一抢购火热进行中,某电商后端实例的日志中出现了502错误码,运维平台监测到该异常并发送告警给相关运维。
在这个过程中,运维元数据发挥了什么作用?回答这个问题前,我们先回顾下元数据是什么。
一、元数据的管理
运维系统中的元数据包括服务、机器及其关联关系。服务元数据有服务名称、所属节点、运维人员以及域名等;机器元数据包含序列号、内存等资产信息,IP、机房等网络信息、自定义标签信息以及运行实例等部署信息。这些数据由资源管理模块维护。
资源管理模块对业务以树的形态划分层级,形成服务树,从上到下依次为产品线、系统和应用三类节点。
每个层级都可以关联机器,且上层节点包含下层节点的机器。
通过添加节点的运维及研发角色,可以实现对服务和机器的权限控制。
这种层级结构将服务与服务,服务与机器关联起来,可以直观的表达服务和机器的归属关系,便于实现权限和配置的继承。
二、元数据的应用场景
智能监控
回到上面的问题,报警流程中,服务所在机器的监控客户端查询自己所属的应用,然后从配置管理模块拉取相应监控配置,实现对日志的监控;监控业务端收到监控数据后,查找该机器对应的节点信息,将报警发送给节点的运维等人员。
此外,在DevOps落地实践中,还存在多种其他应用场景
拓扑视图
服务间关系拓扑可由远程过程调用协议(RPC)间的调用关系链自动更新或者在应用上简单维护服务间上下游关系。根据RPC调用关系链自动更新的关系拓扑图主要用在业务运维上,可以帮助运维人员进行故障诊断,对整个业务系统运行状态和部署架构全局一览,清晰便捷. 应用上手工维护服务间上下游关系,可以用于上线版本依赖控制。上线申请单中指定上线版本依赖服务的版本,上线时系统自动检查依赖的版本是否已经完成上线,如果依赖版本未上线,终止本次操作。
批量运维
基于应用服务树节点及权限,规范化批量任务执行操作。日常运维过程中,运维需要对线上机器进行一些批量操作,比如升级软件版本、打补丁,清理日志等。为了避免手工操作带来的风险,只允许运维同学,选择所属权限目标机器,进行操作。对于高危命令,可添加审批机制,增加流程规范。
堡垒机
当机器规模、人员规模逐渐扩大时,如何管理人、机器、权限会变得很复杂。通过元数据的动态管理,用户只需要在服务树上对人员进行角色设置,即可登录堡垒机,获得自己有权限的列表。通过服务树的角色同样可以添加哪些角色拥有su权限等访问策略控制。
持续交付
持续集成、自动化测试、持续交付都可以基于元数据,实现数据的唯一性管理。研发侧,提交代码,自动触发服务树应用对应的编译任务,根据编译规范生成部署包,放到版本库;运维侧,则对资源进行分配抽象到服务树,将版本库里面的代码发布到服务树实例对应的机器上;对于用户侧,通过负载均衡的接入,可以动态的进行服务树实例流量的开关和扩缩容;部署日志则可以按照应用日志服务模块进行检索,方便排查问题。
三、元数据的查询
在上面的监控流程中,客户端和业务端是机器和服务关系数据的消费方,现实的运维场景中,二者也是运维数据的主要需求方。
客户端指安装在机器上,用以执行特定任务的程序,其需要的数据包括当前机器相关的信息,如机器机房、机架等设备属性和归属节点、部署服务等业务属性。
业务端主要指运维平台中的上层系统,比如监控、部署等,当然也有跨平台的其他系统,其需求涵盖服务、机器与权限之间的相互查询。
大规模运维场景中元数据查询面临的压力
生产环境中,客户端需要频繁发起查询请求,以保证其数据的准确性。持续增长的机器规模给系统带来的压力不容小觑。业务端由于复杂多样的业务场景,其查询条件多种多样,查询频率和规模无法估量、难以控制,对系统可靠性和可用性提出了较高的要求。
传统关系型数据库难以承受高并发的查询压力,简单的缓存又难以满足条件复杂的查询需求。
如何面对以上压力,提供高效高可用的查询服务,是亟需解决的问题。
实现高可用查询--名字服务
为了应对以上两种场景的挑战,Devops引入了专注于提供数据查询的名字服务,既可以实现服务的解耦,防止外部查询影响资源管理模块的性能,又可以提供高效稳定的查询功能。
服务和机器数据由资源管理模块维护,存储到数据库。名字服务定时从资源管理模块同步数据,直接面向其他业务端和客户端提供查询服务。为提高响应速度,减少IO,元数据以map的形式存储于内存中。
名字服务有三个逻辑层级,分别是同步、存储和查询,我们从这三个方面了解下其如何实现高可用:
保证数据的实效性和服务的可扩展性
同步的流程如下 服务启动时:优先从本地存在缓存文件恢复数据,然后增量从资源管理模块同步数据,以减小数据库压力,并快速提供服务;如果没有缓存文件,则从资源管理模块查询全量数据。 服务正常运行时:实时与资源管理模块进行增量数据同步,同步的时间点以上次同步的时间戳为准;为进一步保证数据准确,需定期全量同步数据;定期更新缓存文件。 若同步数据出现异常:不更新当前数据,仅保存异常时时间戳,以后的每次同步时间点从该时间戳开始。
由于该模块定时从资源管理模块增量/全量更新数据,在保证数据的准确性的同时对数据库的压力是线性且可控的,并且运行过程不依赖其他服务,因此查询压力增加时,可以通过水平扩容来迅速提高请求承载量。
通过缓存热点数据提高查询效率
回顾下开始的那个场景:监控客户端会定期查询获取最新的数据。假设每分钟请求一次,那么10万台机器就带来了上千的 qps,如果每个客户端请求多个接口或者每个机器部署多种客户端,这个数值就会翻倍。
针对这种常用的查询场景,名字服务通过缓存热点数据来提高查询性能。
假设客户端需要通过 ip(也可能是uuid)查询实例列表,而内存中实例是以id为key存储的。如果依次遍历全部实例进行ip匹配,会有一定的性能开销。此时如果有一份ip与实例id的关联关系的缓存,即可首先定位到对应实例的id,然后直接获取id对应实例的详情。
诸如此类的缓存,可以是产品线与机器的归属关系、机房与机器的关联关系以及应用与实例从属关系等。
由于数据同步环节是由名字服务主动发起的,所以该索引可以在每次更新之后重新生成,来保证其准确性。
支持多维度数据查询
上述缓存不能穷举所有查询信息,服务节点和机器的属性(如机房、运行环境等)和标签(如报警策略和其他运维自定义的标识等)都可能成为数据查询的条件。针对此种情况,名字服务在缓存数据时将属性和标签解析为key-value模型,使用规定的请求格式便可实现查询。
格式定义为Key1_value1.Keys_value2.keyN_valueN,其中常规属性的key以大写字母开头,自定义标签的 key以小写字母开头。例如,当名字服务收到格式为Product_trade.Idc_huabei.env_pre的查询请求时,会先根据Product获取trade产品线的机器ID集合,然后与huabei机房的机器ID集合取交集,再根据该ID集合获取机器集合,最后在机器集合中根据标签匹配出pre环境的机器集合。 DevOps将元数据的管理与查询业务分开维护,元数据的变更通过资源管理实现,数据查询通过名字服务实现。
资源管理通过层级结构维护了服务和机器的关系,并通过角色实现权限的划分。
名字服务只依赖资源管理,便于搭建,易于扩容,可以提供稳定的服务;结合业务场景,通过对热数据缓存实现了较高的查询效率;支持多条件查询,满足复杂的业务需求。
欢迎点击“ 京东云 ”了解更多精彩内容
系统运维
2019-12-02 10:34:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
使用最小化的设定安装完CentOS7后,进入安装Oracle步骤前,需要安装几个工具。具体步骤: yum -y install vim --vim编辑器 yum -y install unzip --zip文件的解压工具 yum -y install lrzsz --上传下载工具 yum -y update --升级所有包,系统版本和内核,改变软件设置和系统设置
注:使用yum安装前,先保证系统可访问互联网。如果在系统无法访问的情况下,可以配置yum资源中心为镜像文件或者下载rpm包进行安装。
完成工具的安装之后,准备进入Oracle的安装过程。
第一步: 安装必须的依赖包
yum -y install gcc
yum -y install gcc-c++
yum -y install make
yum -y install binutils
yum -y install compat-libstdc++-33
yum -y install elfutils-libelf
yum -y install elfutils-libelf-devel
yum -y install elfutils-libelf-devel-static
yum -y install glibc
yum -y install glibc-common
yum -y install glibc-devel
yum -y install ksh
yum -y install libaio
yum -y install libaio-devel
yum -y install libgcc
yum -y install libstdc++
yum -y install libstdc++-devel
yum -y install numactl-devel
yum -y install sysstat
yum -y install unixODBC
yum -y install unixODBC-devel
yum -y install kernel-headers
yum -y install pcre-devel
yum -y install readline*
yum -y install rlwrap --会提示无可用的软件包,此依赖包需要单独下载后然后安装到服务器上
注意:最后一个rlwrap依赖包,可以再网络上进行下载,安装步骤如下:


第二步: 配置用户及用户组
新增数据库安装用户组oinstall
新增数据库管理用户组dba
新增用户oracle并且添加到oinstall和dba中
配置oracle用户的密码
第三步: 创建Oracle的安装目录,并且进行授权
创建oracle的home目录及base目录,并在此基础上创建数据文件存放目录、软件安装信息文件存放目录、快速恢复区目录。
将/data/目录授权给oracle用户,及分配给dba、oinstall用户组。
更改此目录的权限。
第四步: 在data目录下创建一个software目录存放oracle的安装文件
上传安装文件。
注意:
1)Oracle11gR2的linux版本安装包,可上Oracle官网进行下载。
2)注意software的安装目录权限问题。
第五步: 修改配置文件
修改/etc/sysctl.conf文件,添加以下内容:
fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 1073741824
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
重新加载系统参数:
修改用户限制文件/etc/security/limits.conf
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536
oracle soft stack 10240
修改/etc/pam.d/login文件
session required /lib64/security/pam_limits.so
session required pam_limits.so
修改/etc/profile文件
if [ $USER = "oracle" ]; then
if [ $SHELL = "/bin/ksh" ]; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
fi
第六步: 配置Oracle用户环境变量
切换至oracle用户:
修改.bash_profile文件,并且生效变量:
export ORACLE_BASE=/data/u01/app/oracle
export ORACLE_HOME=/data/u01/app/oracle/product/11.2.0/dbhome_1
export ORACLE_SID=orcl
export ORACLE_UNQNAME=$ORACLE_SID
export PATH=$ORACLE_HOME/bin:$PATH
export NLS_LANG=american_america.AL32UTF8
alias sqlplus='rlwrap sqlplus'
alias rman='rlwrap rman'
第七步: 修改静默安装的响应文件
拷贝一份响应文件至当前目录:
修改响应文件db_install.rsp文件,修改部分内容为:
oracle.install.option=INSTALL_DB_SWONLY
ORACLE_HOSTNAME=server3.com
UNIX_GROUP_NAME=oinstall
INVENTORY_LOCATION=/data/u01/app/oracle/inventory
SELECTED_LANGUAGES=en,zh_CN
ORACLE_HOME=/data/u01/app/oracle/product/11.2.0/dbhome_1
ORACLE_BASE=/data/u01/app/oracle
oracle.install.db.InstallEdition=EE
oracle.install.db.DBA_GROUP=dba
oracle.install.db.OPER_GROUP=dba
DECLINE_SECURITY_UPDATES=true
第八步: 开始静默安装Oracle数据库
切换至数据库管理软件安装目录,需要注意目录的用户及用户组:
开始安装…可以依据提示查看日志(一般需要等2-3分钟)
跳出以下提示,表明安装成功,并且切换至root用户执行这两个脚本。

此时已经完成数据库管理软件的安装。
第九步: 开始静默安装Oracle实例
修改静默安装响应文件/home/oracle/response/dbca.rsp,修改完成后可以预览检查下配置情况:
其余配置可依据实际情况更改。
执行创建Oracle实例:
出现以上提示,标识安装完成。
第十步:开始配置数据库监听
使用响应文件进行监听配置:
/data/u01/app/oracle/product/11.2.0/dbhome_1/bin/netca /silent /responseFile /home/oracle/response/netca.rsp
注意:此处配置数据库监听采用默认的方式,若需要可修改响应文件。
监听配置成功后,在/data/u01/app/oracle/product/11.2.0/dbhome_1/network/admin目录下会产生两个文件:
系统运维
2019-11-29 16:53:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
前置条件:
1.使用Google浏览器
2.打开YAPI官网 → 注册/登录账号 → 进入项目组 → 接口列表
3.安装谷歌插件 → cross-request

操作步骤:
1. 设置全局变量 (这个操作比较蠢笨 下面 步骤3 有个动态的全局token设置 ↓ )
设置token-环境配置-header:参数内容(这里是手动添加token值,会自动全局应用到每个请求接口里面去)
设置完成后,提交保存

2. 添加集合-导入接口1234-开始测试(这里就是接口自动化的测试用例)
查看返回状态、测试报告
查看测试项目的页面返回显示

3. 动态设置全局token(见下图)
设置-请求配置:
Pre-request Script(请求参数处理脚本) :
let token = localStorage.getItem('token');
context.requestHeader[' key-value '] = token;
Pre-response Script(响应数据处理脚本) :
if(context.responseHeader[' key-value '] !== undefined) {
let token = context.responseHeader[' key-value '];
localStorage.setItem('token', token);
}
PS: 从上个接口读取返回值作为下个接口的参数
例 {{ $.用例编号.body.data[0].child[0].id }}
系统运维
2019-11-29 16:38:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
本期带来一篇最近在阿里云服务器上折腾nginx配置网站的教程。
1 nginx简介
nginx是一个轻量级的web服务器,我的认知,这东西跟负载平衡不分家。这里抄下度娘简介。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。——百度百科
接下来给出 官网 。
2 阿里云安装nginx
这里就不多说阿里云服务器的相关内容了,笔者长期有租用一台用于数据处理等工作。系统是Ubuntu 14.02,这里选用Xshell连接服务器进行一系列操作,并用Xftp来上传下载文件。这里安装nginx有两种方式,一种是apt-get的安装,但是这种安装一般不是最新版本。如果想要最新版本,就推荐下载源码,自行编译安装。这里我们就不使用最新版本了。至于编译安装的可以在网上搜索教程,关键就是先安装几个关键依赖库openssl,zlib,pcre,同时编译安装也比较自由,可以在自己定义的路径里安装。 apt-get update apt-get install nginx
如果apt-get报错如图的话。并且无法安装任何软件包的话,就必须执行第一行update的命令行。
执行完update命令行,如图。
接着执行安装语句。键盘敲入y即可安装。
安装成功后,可以键入如下命令检测。 nginx -v
说起来这版本确实旧。目前官网最新版本为1.17。
3 配置nginx
我们首先了解下nginx的目录,默认安装的目录主要在/etc文件夹下。
这个时候,只需要在命令行里敲入nginx,即运行了nginx。 nginx
由于我的阿里云之前只打开了22端口用于Xshell连接,这里就多打开默认的80端口访问网站。打开阿里云官网,登录账户,点击云服务器ECS,如图点击安全组。
接着在主面板点击配置规则。
然后点击添加安全组规则,按如图所示填写页面的80端口。0.0.0.0/0表示任意ip可以访问。
接下来把服务器ip地址放到浏览器中,即可发现跳转到nginx的欢迎页面。
接下来只需要把网页放到服务器中的指定位置即可,再针对配置文件做修改。有域名的条件下,可以把域名和自己服务器关联起来做解析。
这个版本的nginx的文件配置不是nginx目录下的nginx.conf,而是site-available文件夹下的default。这里给出一个测试的配置。
root是网站的路径。这里采用二级域名来控制,所以还得去配置域名。具体的教程可以看后面的参考链接。这里就不赘述了。
4 基本命令以及错误
这里的一些命令主要是开启nginx,关闭,重启,关闭所有nginx。 # 关闭 nginx -s stop # 查询80端口占用 netstat -ntpl | grep 80 # 杀死所有nginx进程 killall nginx
详细的命令可以参考后面的链接。
另外我在启动nginx时报了两次80端口占用的信息。
这个应该是多启动了一次nginx(猜想)。此外网上也有不少人遇到第二个端口ipv6占用问题,真正的措施并不是kill掉所有nginx,而是配置文件中的修改。这些参考链接我一并列出,有需要者自行取用。
参考链接:
1. Nginx安装以及解决运行时端口被占用问题
2. nginx的启动和关闭
3. nginx - nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
4. Hugo 与 nginx 结合使用
5. 解决nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
6. 把域名和IP地址绑定后,利用域名+端口号访问自己搭建的网站
7. Nginx停止服务和各种命令
系统运维
2019-12-02 00:12:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
(1)iptables 4种配置的方法
(2)firewalld 4种网卡设置的方法
系统运维
2019-12-01 23:14:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
(1)RAID0依次,RAID1重复,RAID5奇偶校验,RAID10安全性和读写速度
(2)mdadm管理
(3)PV物理卷,VG卷组,LV逻辑卷
(4)扩容逻辑卷 lvextend
(5)缩小逻辑卷 lvreduce
(6)删除逻辑卷 lvremove
系统运维
2019-12-01 22:34:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
(1)mkswap
(2)xfs_quota
(3)edquota
(4)ln创建链接文件
系统运维
2019-12-01 22:18:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
(1)一切都是从“/”开始的
(2)/dev/sda5
(3)XFS
(4) mount,unmount
(5)fdisk分区
mkfs.XXX格式化
mount 挂载
(6)du
系统运维
2019-12-01 22:08:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
通用规则 Agent Agent通常是一个机器或容器,它连接到Jenkins主机,并在主控器指导时执行任务。 Artifact 在Build或Pipeline 运行期间生成的不可变文件,该文件归档到Jenkins Master上以供用户随后检索。
Build 项目 单次执行的结果
Cloud 提供动态代理 配置和分配的系统配置,例如由Azure VM Agents 或 Amazon EC2插件提供的配置和分配 。
Core 主要的Jenkins应用程序(jenkins.war)提供了 可以构建Plugins的基本Web UI,配置和基础。
Downstream 配置Pipeline或项目时被触发作为一个单独的Pipeline或项目的执行的一部分。
Executor 用于执行由节点上的Pipeline或 项目定义的工作的插槽。节点可以具有零个或多个配置的执行器,其对应于在该节点上能够执行多少并发项目或Pipeline。
Fingerprint 考虑全局唯一性的哈希追踪跨多个Pipeline或项目的工件或其他实体 的使用 。
Folder 类似于文件系统上的文件夹的Pipeline和/或 项目 的组织容器。
Item Web UI中的实体对应于:Folder, Pipeline, or Project.
Job 一个不推荐的术语,与项目同义。
Label 用于分组代理的用户定义的文本,通常具有类似的功能或功能。例如linux对于基于Linux的代理或 docker适用于支持Docker的代理。
Master 存储配置,加载插件以及为Jenkins呈现各种用户界面的中央协调过程。
Node 作为Jenkins环境的一部分并能够执行Pipeline或项目的机器。无论是the Master还是Agents都被认为是Nodes。
Project 用户配置的Jenkins应该执行的工作描述,如构建软件等。
Pipeline 用户定义的连续输送Pipeline模型,以便更多阅读本手册中的“ Pipeline”一章。
Plugin 与Jenkins Core分开提供的Jenkins功能扩展。
Publisher 完成发布报告,发送通知等的所有配置步骤后的 构建的 一部分。
Stage stage是Pipeline的一部分,用于定义整个Pipeline的概念上不同的子集,例如:“构建”,“测试”和“部署”,许多插件用于可视化或呈现Jenkins Pipeline状态/进度。
Step 单一任务从根本上讲,指的是Jenkins 在Pipeline或项目中做了什么。
Trigger 触发新Pipeline运行或构建的标准。
Update Center 托管插件和插件元数据的库存,以便在Jenkins内部进行插件安装。
Upstream 配置的Pipeline或项目,其触发单独的Pipeline或项目作为其执行的一部分。
Workspace Noede文件系统上的一次性目录, 可以由Pipeline或项目完成工作。在Build或 Pipeline运行完成后,工作区通常会保留原样,除非在Jenkins Master上已经设置了特定的Workspace清理策略。
系统运维
2019-12-01 20:03:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
D 语言曾经兴盛过,也随着信息技术发展而颓废过,但最终我们很高兴的看到它又带着强烈的自信开始复苏,希望通过本文让现代计算机科学工作者进一步了解这门具有独特魅力的编程语言。
引言
D 语言是一门语法相当优雅的编译型语言,自 1999 年发布至今已发展了 20 年,它既拥有 Java 那样强大的表现力,又具有 C++ 相当的性能,本来是一门未来相当明朗的语言,但是当年因为 2.x 版本破坏性升级导致社区大量核心开发者将其放弃。
2010 年 ,伴随着 Andrei Alexandrescu 新书《The D Programming Language》的出版,D 语言又变得活跃起来,D 语言 2.0 的特性变得稳定,运行库与标准库的分离,解决了 D 语言 1.0 时期标准库之争的问题。
2011 年 ,D 语言的开发迁移到了 Github,在有了更好的代码管理和 bug 跟踪方式之后,参与到 D 语言编译器、运行库和标准库开发的人员也有了明显的增加。次年,D 语言 1.0 版本停止更新,开发者全力投入到 2.0 的开发。
2014 年 ,D 语言编译器前端代码的许可协议变更为更加宽松的 Boost 许可。在 2017 年,编译器所有代码最终都使用了 Boost 许可。在解决编译器源码许可问题之后,D 语言在开源社区中变得更加开放,并顺利合并进入了 GCC 9.x。
直到 2015 年 ,D 语言社区进一步恢复活力,基于包管理的构建方式开始成熟,大量的开发库开始涌现并应用到实际项目中。目前,已注册项目库达 1 千 6 百多个。
重新燃起希望的 D 语言在版本发布的规划上非常稳健,直至今日来说每两个月都可以保证一个大版本的发布。平均每个版本的开发者数量都有超过 50 个核心贡献者,最近的 2.087.0 更是达到了 62 位核心开发者的贡献。
编程语言的战争异常惨烈,本文希望通过介绍,让开发者重新来了解一下 D 语言,认识到 D 语言其实是一门能力强大的语言,并且它可以用于不同的场景,生态也在不断发展完善中。
第一部分:D 语言主要特点
D 语言是在吸取 C++ 遇到的各种教训基础上设计出来的,拥有与之类似的编程风格,许多概念与 C 或 C++ 都是相通的。不过,D 语言也有自己的一些特点,如支持闭包、匿名函数、编译时函数执行、支持垃圾回收等。具体来讲,D 语言拥有以下几个主要特点:
面向对象编程
D 语言允许定义类和接口。像 Java 一样,D 语言的继承模型是单类继承和多接口继承。所有的类都有一个根类 Object。D 语言的类和接口都是引用类型,而结构是值类型,且不允许继承。
函数式编程
D 语言像 C++ 一样,允许在类或结构外单独定义函数。它还提供了各种不可变数据类型、匿名函数和闭包、UFCS(统一函数调用语法)等特性来更好地支持函数式编程。
泛型编程
D 语言允许定义模型类型,也支持直接定义模板类和模板函数。模板允许嵌套定义,模板方法甚至允许递归调用。通过模板约束可以实现模板类型重载。模板参数支持不定个数类型。除此以外,模板参数类型还支持自动推导。
元编程
D 语言里的纯函数不会对全局变量产生任何影响,因此可以在编译时直接调用。借助 static if、static foreach、mixin 等语句,可以编写在编译时执行的代码,动态生成代码,满足快速定制应用功能的需求。
安全内存
默认支持基于垃圾回收的内存管理方式,从而让编程变得更简单,内存变得安全,程序变得更稳定。除此之外,也可以根据需要对关键的内存资源选择手动管理方式。借助 scope 语句,可以很好地控制内存资源申请和释放点。D 语言内部有一套核心的类型定义和实现,它是 D 语言的一个子集,也被称作 SafeD,用于保护内存的安全。
模块化编程
D 语言的每一个源文件都被定义为一个模块(module),源文件之间的依赖即体现了模块之间的依赖。同一目录下的多个模块可以组成一个包(package)。基于模块的代码让项目的逻辑变得更加清晰,也为项目的快速构建和编译提供了支持。
其他语言交互
D语言的ABI与C语言完全兼容,因此它也具有很好的与其他语言交互的能力,如与 C、C++ 和 Objective-C 等语言进行交互编程。D 语言甚至支持直接嵌入汇编语言,部分性能关键的代码可以直接使用汇编语言来实现。D 语言的 BetterC 特性是 D 语言的一个子集,能完全去除 GC 依赖,并以更好 C 语言的方式来代替 C 语言编程,它能胜任 C 语言做的绝大部分工作。在 Windows 平台下,可以使用 COM 接口实现与其他语言的交互。
基于包的应用构建
这个不属于 D 语言本身特性,但是在 D 语言的开发生态里,这是一种很非常重要和便捷的 D 语言应用构建方式。dub 是 D 语言的应用构建工具,它可以很好地管理应用包之间的依赖关系,快速地构建出 D 语言应用。
除了上述特点,D 语言还提供了许多其他特性,如内建关联数组、单元测试、内联汇编、内嵌文档等,这些特性让 D 语言成为了一门功能强大的语言。
第二部分:与其它语言的简要对比
D 语言与 Java 相比
众所周知 Java 对工业化架构的设计非常棒,远超越 C++、Golang 等语言,能与 Java 相提并论的只有 C#,在研究中我们发现 D 同样具备工业化的特性,而且不需要那么庞杂的虚拟机开发环境,D 的性能比起 Java 来说好的非常明显,而且整合 C、C++ 库的时候也非常方便,而 Java 想整合 C、C++ 就需要非常麻烦的 jni 对去接。毕竟 D 语言是名副其实的系统级开发语言,D 语言在面向对象方面并不像 Java 那样强制每个文件都是对象,而更像 C++ 那样拥有一个 main() 函数作为程序入口。
示例代码 import std.stdio; void main() { writeln("Hello world!"); }
D 语言与 C++ 相比
说到性能,C++ 一直占据服务端高性能的首选,但是 D 的性能与 C++ 相比几乎打成平手,但效率可以 3~5 倍于 C++。当然 D 与 C 语言各种库整合同样方便,因为 D 语言是二进制与 C、C++ 兼容的,语法更像是 C++ 的超级升级版,D 在对 hashMap 操作时性能比 C++ 还要高,而且只要是掌握 C++ 的人可以没有任何门槛地使用 D 语言。
示例代码 import std.stdio; void main() { foreach(i; 1..10) { writeln(i); } }
D 语言与 PHP 相比
PHP 是服务端 脚本 语言占有率最高的语言,PHP 的优势就是简单,无需引入什么包就可以使用语言本身的所有函数,但是也就是这样 PHP 的性能一直没有明显改进,虽然说 PHP 7.x 的出现让 PHP 的性能提升了 2.x 倍,但是那只是和非常慢的 PHP 5.x 相比而已,与编译型语言相比还是相差太多。PHP 有非常明显的短板,比如不支持多线程、长连接不友好、弱类型、跨语言 RPC 协议支持不稳定、部署需要 PHP 运行环境等,而 D 语言具备 C++ 可实现的所有功能,包括内嵌汇编,开发效率上来讲与 PHP 相比只是多了个强类型的概念,而 D 语言标准库也提供 to 方法让你非常方便地进行各种类型的转换。
示例代码 import std.stdio : writeln; import std.conv : to; void main() { int i = 10000; string s = "Is string "; s ~= i.to!string; // PHP 使用点连接两个字符串,而 D 语言使用波浪线连接两个字符串 writeln(s); // 输出结果 Is string 10000 }
D 语言可替代 C 语言
前阵子有一篇文章比较火,有一位 i3 核心开发者在文章中说到,D 才是真正替代 C 的首选语言,他认为 D 二进制与 C、C++ 完全兼容所以可直接使用这两个语言的二进制库,D 甚至可以用 dpp 项目直接 #include 语法引入 *.h 文件,作者同时也说到为什么 C 的替代者不是 Rust 和 Golang,有兴趣的同学可以自行了解原文《D as a C Replacement》。
gcc 整合 D 语言编译支持
这是一个非常大的进步,在近期发布的 gcc 9.1 大版本中整合了 DLang 全新的编译器前端也就是 gdc,现在整个社区有更多开发者对 D 项目进行推进,也有更多人在使用 D 完成之前 C/C++ 的工作。
第三部分:D 语言主要应用
作为一门支持 GC 的系统语言,D 语言已被许多公司采纳和应用,其中不乏像 Facebook、eBay 这样的大公司。D 的应用涉及了游戏、Web 应用、GUI 应用、操作系统、编译器、嵌入式、科学计算与教育等多个领域。
游戏开发
Remedy 公司已成功地用 D 语言将一款 3A 游戏 Quantum Break 移植到了 XBox One 和 Windows 10 平台。另外,有纯 D 语言实现的 3D 游戏引擎 Dash 和 D 语言游戏开发工具库 gfm。
Web 框架
编程语言在 Web 服务端框架非常重要,有好用的框架可以让整个语言充满活力,就像 Java 有一个 Spring Framework 框架,PHP 有一个 laravel 框架,Python 拥有一个 Django,而 Ruby 拥有 Rails,所以既然是构建服务端应用 DLang 也同样拥有一个代表性的框架 Hunt Framework。
数据库操作
数据库操作是大部分应用项目都不可或缺的一个基本操作,操作方式主要有两种:编写 SQL 脚本 和 ORM。
直接操作数据库的 D 语言开库有 ddbc / (http://code.dlang.org/packages/ddbc)hunt-database 等,支持的数据库包括 MySQL、PostgreSQL 和 SQLite 等。其中,新版本的 hunt-database 的底层驱动库已从绑定 C 语言的方式升级为了直接使用 D 语言实现,减少了对第三方库的依赖。
采用 ORM 方式的 D 语言开库有 hibernated / hunt-entity 等。其中,hunt-entity 借鉴了 Java JPA 和 spring-data-jpa 的概念,工业化程度高,操作合理并且易于维护。
微服务相关
hunt-service 是基于 gRPC 协议的分布式 RPC 服务器与客户端库,很容易使用,也非常方便与 hunt-framework 整合构建微服务架构。
neton 是基于 raft 算法的分布式服务发现注册应用服务。
GUI 应用
其实 D 语言的推出比较早,所以 GTK 的整合非常完整,众所周知 gtk 官方的 vala 语言也大量借鉴了 D 的语言设计,所以 gtkd 能够非常方便的构建客户端应用,官方也有开发者推出了新的教程站点非常棒:gtkDcoding | Simple examples of how to use GtkD to build GUI applications(https://gtkdcoding.com/)
此外,纯 D 语言实现的跨平台 GUI 库 dlangui 也有不俗的表现,有一个 DLangIDE 就是基于它实现的。更多 GUI 库可以参考这里。
系统应用
在编译器方面,DMD 前端已实现自举。在操作系统方面,有 PowerNex(https://github.com/xomboverlord/xomb/tree/unborn) 与 Trinix 等系统尝试。编译器 LDC 甚至允许在更多的系统平台下进行应用开发,如支持基于 ARM 和 MIPS 架构的嵌入式系统、Android 系统等。
科学计算
现在使用 D 语言可以方便的进行科学计算,mir 是其中的佼佼者,它对多维数组计算提供了优秀的支持,性能超越了许多数值计算库,达到商业水平。
结语
简单来说,D 语言是一门在各个领域具有优势的编程语言,同时它当前的生态也在不断发展,本文希望通过简单的介绍,让开发者重新认识 D 语言。如果你还不了解 D 语言,读完本文,希望你对它产生兴趣;如果你此前有听说过 D 语言,读完本文,希望你能重新认识它;如果你对 Web 开感兴趣,请持续关注本系列接下来的 Web 应用篇。 本文地址: https://www.linuxprobe.com/basic-part-d-language.html
系统运维
2019-12-01 16:54:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
很多时候,大中型网站为了静态资源分布式部署,加快访问速度,减轻主站压力,会把静态资源(例如字体文件、图片等)放在独立服务器或者CDN上,并且使用独立的资源域名(例如res.test.com)
但是在实际部署中,会发现浏览器无法载入这些不同域名的资源,firefox控制台会报错:
[html] view plain copy
已阻止跨源请求:同源策略禁止读取位于 http://xxxxx 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。 已阻止跨源请求:同源策略禁止读取位于 http://xxxxx 的远程资源。(原因:CORS 请求失败)。
这是因为现代浏览器将其定义为跨域资源而不允许加载
理解跨域首先必须要了解同源策略。同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。
何谓同源:
URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
同源策略:
浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。 (白帽子讲web安全[1])
从一个域上加载的脚本不允许访问另外一个域的文档属性。
那么关键是如何解决呢,其实很简单,只要在静态资源服务器上,增加一个头信息:
Access-Control-Allow-Origin *
本文就apache进行操作,nginx大同小异
首先编辑httpd.conf
找到这行
#LoadModule headers_module modules/mod_headers.so
把#注释符去掉
LoadModule headers_module modules/mod_headers.so
目的是开启apache头信息自定义模块
然后在独立资源域名的虚拟主机添加一行
Header set Access-Control-Allow-Origin *
意思是对这个域名的资源进行访问时,添加一个头信息
重启apache
再访问,OK! NameVirtualHost 10.0.0.2:80 DocumentRoot /var/www/host.example.com ServerName host.example.com JkMount /webapp/* jkworker Header set Access-Control-Allow-Origin "*" RewriteEngine on RewriteRule ^/otherhost http://otherhost.example.com/webapp [R,L]
And here's an example of the Apache config for the second: NameVirtualHost 10.0.1.2:80 DocumentRoot /var/www/otherhost.example.com ServerName otherhost.example.com JkMount /webapp/* jkworker Header set Access-Control-Allow-Origin "*"
Buy me a cup of coffee :)
系统运维
2019-11-30 20:43:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
设置用户权限配置文件的权限 | 文件权限
描述
设置用户权限配置文件的权限
加固建议
执行以下5条命令 chown root:root /etc/passwd /etc/shadow /etc/group /etc/gshadow chmod 0644 /etc/group chmod 0644 /etc/passwd chmod 0400 /etc/shadow chmod 0400 /etc/gshadow
操作时建议做好记录或备份
确保SSH LogLevel设置为INFO | 服务配置
描述
确保SSH LogLevel设置为INFO,记录登录和注销活动
加固建议
编辑 /etc/ssh/sshd_config 文件以按如下方式设置参数 (取消注释): LogLevel INFO
操作时建议做好记录或备份

设置SSH空闲超时退出时间 | 服务配置
描述
设置SSH空闲超时退出时间,可降低未授权用户访问其他用户ssh会话的风险
加固建议
编辑/etc/ssh/sshd_config,将ClientAliveInterval 设置为300到900,即5-15分钟,将ClientAliveCountMax设置为0。
ClientAliveInterval 900 ClientAliveCountMax 0
ClientAliveCountMax 和ClientAliveInterval 取消注释符号#
操作时建议做好记录或备份

SSHD强制使用V2安全协议 | 服务配置
描述
SSHD强制使用V2安全协议
加固建议
编辑 /etc/ssh/sshd_config 文件以按如下方式设置参数: Protocol 2
操作时建议做好记录或备份
确保SSH MaxAuthTries设置为3到6之间 | 服务配置
描述
设置较低的Max AuthTrimes参数将降低SSH服务器被暴力攻击成功的风险。
加固建议
在/etc/ssh/sshd_config中 取消MaxAuthTries注释符号# ,设置最大密码尝试失败次数3-6,建议为4: MaxAuthTries 4
操作时建议做好记录或备份

禁止SSH空密码用户登录 | 服务配置
描述
禁止SSH空密码用户登录
加固建议
在/etc/ssh/sshd_config中 取消PermitEmptyPasswords no注释符号#
操作时建议做好记录或备份
重启Apache systemctl restart httpd

设置密码修改最小间隔时间 | 身份鉴别
描述
设置密码修改最小间隔时间,限制密码更改过于频繁
加固建议
在 /etc/login.defs 中将 PASS_MIN_DAYS 参数设置为7-14之间,建议为7: PASS_MIN_DAYS 7 需同时执行命令为root用户设置: chage --mindays 7 root
操作时建议做好记录或备份
设置密码失效时间 | 身份鉴别
描述
设置密码失效时间,强制定期修改密码,减少密码被泄漏和猜测风险,使用非密码登陆方式(如密钥对)请忽略此项。
加固建议
使用非密码登陆方式如密钥对,请忽略此项。 在 /etc/login.defs 中将 PASS_MAX_DAYS 参数设置为 60-180之间, 如 PASS_MAX_DAYS 90 。需同时执行命令设置root密码失效时间: chage --maxdays 90 root
操作时建议做好记录或备份

重启Apache
systemctl restart httpd systemctl restart sshd

限制编译器
如果你的系统被黑掉了,那么攻击者会对系统使用的是哪种编译器很感兴趣。为什么呢?因为他们可以去下载一个简单的C文件(POC),并且在你的系统上进行编译,从而在几秒钟之内就成为了root用户。如果编译器是开启的话,他们还可以在你的系统上做一些严重的破坏。
首先,你需要检查单个的数据包以确定其包含有哪些二进制文件。然后你需要限制这些二进制文件的权限。 $ rpm -q --filesbypkg gcc | grep 'bin'
现在我们需要创建一个可以访问二进制文件的编译器的组名称了: $ groupadd compilerGroup
然后,你可以赋予这个组能够改变任何二进制文件的所有权: $ chown root:compilerGroup /usr/bin/gcc
最后重要的是:仅编译器组才有改变该二进制文件的权限: $ chmod 0750 /usr/bin/gcc
至此,任何试图使用gcc的用户将会看到权限被拒绝的信息了。
Buy me a cup of coffee :)
系统运维
2019-11-30 20:43:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
lsb_release -a
Buy me a cup of coffee :)
系统运维
2019-11-30 20:43:00
「深度学习福利」大神带你进阶工程师,立即查看>>> # php -v 查看全部php软件包
#rpm -qa|grep php
提示如下: php-cli-5.4.16-46.el7.x86_64 php-process-5.4.16-46.el7.x86_64 php-pear-1.9.4-21.el7.noarch php-mbstring-5.4.16-46.el7.x86_64 php-5.4.16-46.el7.x86_64 php-snmp-5.4.16-46.el7.x86_64 php-soap-5.4.16-46.el7.x86_64 php-xml-5.4.16-46.el7.x86_64 php-gd-5.4.16-46.el7.x86_64 php-mysql-5.4.16-46.el7.x86_64 php-ldap-5.4.16-46.el7.x86_64 php-common-5.4.16-46.el7.x86_64 php-pdo-5.4.16-46.el7.x86_64 php-odbc-5.4.16-46.el7.x86_64 php-xmlrpc-5.4.16-46.el7.x86_64 删除PHP版本
# rpm -e php-mysql-5.4.16-46.el7.x86_64
# rpm -e php-odbc-5.4.16-46.el7.x86_64
# rpm -e php-pdo-5.4.16-46.el7.x86_64
# rpm -e php-xml-5.4.16-46.el7.x86_64
# rpm -e php-cli-5.4.16-46.el7.x86_64
# rpm -e php-gd-5.4.16-46.el7.x86_64
# rpm -e php-common-5.4.16-46.el7.x86_64
Buy me a cup of coffee :)
系统运维
2019-11-30 20:42:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
常见HTTP请求错误码大全 The definition of errno and errmsg
https://gitee.com/owenzhang24/error_code

Buy me a cup of coffee :)
系统运维
2019-11-30 20:42:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
shell习题解析56_60
https://github.com/jjjfan/shell_devops/blob/master/Shell%E4%B9%A0%E9%A2%98%E8%A7%A3%E6%9E%90/shell%E4%B9%A0%E9%A2%98%E8%A7%A3%E6%9E%9056_60.md
系统运维
2019-11-30 20:37:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
Apollo(阿波罗)是携程框架部门研发的配置管理平台,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring环境也有较好的支持。.Net客户端不依赖任何框架,能够运行于所有.Net运行时环境,而且已经支持.NET Core。
官网: https://github.com/ctripcorp/apollo
Wiki: https://github.com/ctripcorp/apollo/wiki (一切的集成方式和使用方法都在这里)
Issues: https://github.com/ctripcorp/apollo/issues (如果期间有任何问题,请通过这里查找大部分解决方法)
说明:官方提供了分布式部署方案,但是基于本地开发和调试上一般是单机部署的比较多。且提供的Quick Start方案跑不起来。所以下面将针对单机搭建上做详细的实践,用作开发环境。
注意:如果是生产环境一定要使用分布式部署方案来做高可用集群。
下载Release版本: https://github.com/ctripcorp/apollo/releases
1、环境:
JDK:1.8.0_161
Maven:3.5.2
MySQL:5.7.18
apollo:0.9.1
2、解压
wget  https://github.com/ctripcorp/apollo/archive/v0.9.1.tar.gz
tar zxvf apollo-0.9.1.tar.gz
3、导入数据库文件
登录MySQL命令行,然后执行
/data/apollo/apollo-0.9.1/scripts/sql/apolloconfigdb.sql
/data/apollo/apollo-0.9.1/scripts/sql/apolloportaldb.sql
4、打包
修改/data/apollo/apollo-0.9.1/scripts/build.sh,把数据库账号密码修改为我们的密码以及mysql 服务器地址。只保留dev_meta,其他的都删除
dev_meta= http://localhost:8080
META_SERVERS_OPTS="-Ddev_meta=$dev_meta"
然后执行
./build.sh
该脚本会依次打包apollo-configservice, apollo-adminservice, apollo-portal和apollo-client。
5、启动
apollo-configservice:
切换到目录 /data/apollo/apollo-0.9.1/apollo-configservice/target,解压apollo-configservice-0.9.1-github.zip
unzip apollo-configservice-0.9.1-github.zip –d test
执行脚本启动服务
./startup.sh
apollo-adminservice:
切换到目录 /data/apollo/apollo-0.9.1/apollo-adminservice/target,解压apollo-adminservice-0.9.1-github.zip
unzip apollo-adminservice-0.9.1-github.zip –d test
执行脚本启动服务
./startup.sh
apollo-portal:
apollo-portal的默认端口是8080,和apollo-configservice一致,所以如果需要在一台机器上同时启动apollo-portal和apollo-configservice的话,需要修改apollo-portal的端口。直接修改startup.sh中的SERVER_PORT即可,如SERVER_PORT=8070。
切换到目录 /data/apollo/apollo-0.9.1/apollo-portal/target,解压apollo-portal-0.9.1-github.zip
unzip apollo-portal-0.9.1-github.zip –d test
修改端口:
执行脚本启动服务
./startup.sh
6、访问
http://localhost:8070  ,默认用户名/密码参考  Portal 实现用户登录功能 。
启动 cat /lib/systemd/system/apolloportal.service [Unit] Description= apollo-portal After=network.target [Service] Type=forking User=root Group=admin WorkingDirectory=/data/test/apollo/portal ExecStart=/data/test/apollo/portal/scripts/startup.sh ExecStop=/data/test/apollo/portal/scripts/shutdown.sh Restart=always RestartSec=30 [Install] WantedBy=multi-user.target cat /lib/systemd/system/apolloconfig.service [Unit] Description= apollo-config After=network.target [Service] Type=forking User=root Group=admin WorkingDirectory=/data/test/apollo/config ExecStart=/data/test/apollo/config/scripts/startup.sh ExecStop=/data/test/apollo/config/scripts/shutdown.sh Restart=always RestartSec=30 [Install] WantedBy=multi-user.target cat /lib/systemd/system/apolloadmin.service [Unit] Description= apollo-adminservice After=network.target [Service] Type=forking User=root Group=admin WorkingDirectory=/data/test/apollo/admin ExecStart=/data/test/apollo/admin/scripts/startup.sh ExecStop=/data/test/apollo/admin/scripts/shutdown.sh Restart=always RestartSec=30 [Install] WantedBy=multi-user.target
系统运维
2019-11-30 18:40:07
「深度学习福利」大神带你进阶工程师,立即查看>>>
在实际项目中Redis常被应用于做缓存,分布式锁、消息队列等。但是在搭建配置好Redis服务器后很多朋友应该会发现和有这样的疑问,为什么Redis默认建立了16个数据库?
在实际项目中Redis常被应用于做缓存,分布式锁、消息队列等。但是在搭建配置好Redis服务器后很多朋友应该会发现和有这样的疑问,为什么Redis默认建立了16个数据库,如下图所示。
一、16个数据库的由来
Redis是一个字典结构的存储服务器,一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与在一个关系数据库实例中可以创建多个数据库类似(如下图所示),所以可以将其中的每个字典都理解成一个独立的数据库。
以MySQL实例为例
Redis默认支持16个数据库,可以通过调整Redis的配置文件redis/redis.conf中的databases来修改这一个值,设置完毕后重启Redis便完成配置。
客户端与Redis建立连接后会默认选择0号数据库,不过可以随时使用SELECT 命令 更换数据库。 # 切库 redis> SELECT 1 # 默认0号db,切换为1号db OK redis [1] > GET username # 从1号库中获取 username (nil)
在实际项目中则可以通过以Redis配置文件的形式指定数据库,如下图所示
二、正确理解Redis的“数据库”概念
由于Redis不支持自定义数据库的名字,所以每个数据库都以编号命名。开发者则需要自己记录存储的数据与数据库的对应关系。另外Redis也不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部数据库,要么全部数据库都没有权限访问。但是,要正确地理解Redis的“数据库”概念这里不得不提到一个 命令 : # 清空一个Redis实例中所有数据库中的数据 redis 127.0.0.1:6379> FLUSHALL
该命令可以清空实例下的所有数据库数据,这与我们所熟知的关系型数据库所不同。关系型数据库多个库常用于存储不同应用程序的数据 ,且没有方式可以同时清空实例下的所有库数据。所以对于Redis来说这些db更像是一种命名空间,且不适宜存储不同应用程序的数据。比如可以使用0号数据库存储某个应用生产环境中的数据,使用1号数据库存储测试环境中的数据,但不适宜使用0号数据库存储A应用的数据而使用1号数据库B应用的数据,不同的应用应该使用不同的Redis实例存储数据。Redis非常轻量级,一个空Redis实例占用的内在只有1M左右,所以不用担心多个Redis实例会额外占用很多内存。
三、集群情况下是否支持一个实例多个db?
要注意以上所说的都是基于单体Redis的情况。而在集群的情况下不支持使用select命令来切换db,因为Redis集群模式下只有一个db0。再扩展一些集群与单机Reids的区别,感兴趣的朋友可以去查阅相关的资料深入理解,这里就不做讨论了。 key批量操作支持有限:例如mget、mset必须在一个slot Key事务和Lua支持有限:操作的key必须在一个节点 key是数据分区的最小粒度:不支持bigkey分区 不支持多个数据库:集群模式下只有一个db0 复制只支持一层:不支持树形复制结构
四、总结
Redis实例默认建立了16个db,由于不支持自主进行数据库命名所以以dbX的方式命名。默认数据库数量可以修改配置文件的database值来设定。对于db正确的理解应为“命名空间”,多个应用程序不应使用同一个Redis不同库,而应一个应用程序对应一个Redis实例,不同的数据库可用于存储不同环境的数据。最后要注意,Redis集群下只有db0,不支持多db。 本文地址: https://www.linuxprobe.com/redis-16-mysql.html
系统运维
2019-11-30 11:40:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
很多 SQL 查询都是以 SELECT 开始的。不过,最近我跟别人解释什么是窗口函数,我在网上搜索”是否可以对窗口函数返回的结果进行过滤“这个问题,得出的结论是”窗口函数必须在 WHERE 和 GROUP BY 之后,所以不能”
很多 SQL 查询都是以 SELECT 开始的。
不过,最近我跟别人解释什么是窗口函数,我在网上搜索”是否可以对窗口函数返回的结果进行过滤“这个问题,得出的结论是”窗口函数必须在 WHERE 和 GROUP BY 之后,所以不能”。
于是我又想到了另一个问题:SQL 查询的执行顺序是怎样的?
好像这个问题应该很好回答,毕竟自己已经写了上万个 SQL 查询了,有一些还很复杂。但事实是,我仍然很难确切地说出它的顺序是怎样的。
SQL 查询的执行顺序
于是我研究了一下,发现顺序大概是这样的。SELECT 并不是先执行的,而是在第五个。
这张图回答了以下这些问题
这张图与 SQL 查询的语义有关,让你知道一个查询会返回什么,并回答了以下这些问题: 可以在 GRROUP BY 之后使用 WHERE 吗?(不行,WHERE 是在 GROUP BY 之后!) 可以对窗口函数返回的结果进行过滤吗?(不行,窗口函数是 SELECT 语句里,而 SELECT 是在 WHERE 和 GROUP BY 之后) 可以基于 GROUP BY 里的东西进行 ORDER BY 吗?(可以,ORDER BY 基本上是在最后执行的,所以可以基于任何东西进行 ORDER BY) LIMIT 是在什么时候执行?(在最后!)
但数据库引擎并不一定严格按照这个顺序执行 SQL 查询,因为为了更快地执行查询,它们会做出一些优化,这些问题会在以后的文章中解释。
所以: 如果你想要知道一个查询语句是否合法,或者想要知道一个查询语句会返回什么,可以参考这张图; 在涉及查询性能或者与索引有关的东西时,这张图就不适用了。
混合因素:列别名
有很多 SQL 实现允许你使用这样的语法: SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*) FROM table GROUP BY full_name
从这个语句来看,好像 GROUP BY 是在 SELECT 之后执行的,因为它引用了 SELECT 中的一个别名。
但实际上不一定要这样,数据库引擎可以把查询重写成这样: SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*) FROM table GROUP BY CONCAT(first_name, ' ', last_name)
这样 GROUP BY 仍然先执行。
数据库引擎还会做一系列检查,确保 SELECT 和 GROUP BY 中的东西是有效的,所以会在生成执行计划之前对查询做一次整体检查。
数据库可能不按照这个顺序执行查询(优化)
在实际当中,数据库不一定会按照 JOIN、WHERE、GROUP BY 的顺序来执行查询,因为它们会进行一系列优化,把执行顺序打乱,从而让查询执行得更快,只要不改变查询结果。
这个查询说明了为什么需要以不同的顺序执行查询: SELECT * FROM owners LEFT JOIN cats ON owners.id = cats.owner WHERE cats.name = 'mr darcy'
如果只需要找出名字叫“mr darcy”的猫,那就没必要对两张表的所有数据执行左连接,在连接之前先进行过滤,这样查询会快得多,而且对于这个查询来说,先执行过滤并不会改变查询结果。

Happy girl is playing with group of books in studio
数据库引擎还会做出其他很多优化,按照不同的顺序执行查询,不过我并不是这方面的专家,所以这里就不多说了。推荐:MySQL全面优化,速度飞起来。
LINQ 的查询以 FROM 开头
LINQ(C# 和 VB.NET 中的查询语法)是按照 FROM…WHERE…SELECT 的顺序来的。这里有一个 LINQ 查询例子: var teenAgerStudent = from s in studentList where s.Age > 12 && s.Age < 20 select s;
pandas 中的查询也基本上是这样的,不过你不一定要按照这个顺序。我通常会像下面这样写 pandas 代码: df = thing1.join(thing2) # JOIN df = df[df.created_at > 1000] # WHERE df = df.groupby('something', num_yes = ('yes', 'sum')) # GROUP BY df = df[df.num_yes > 2] # HAVING, 对 GROUP BY 结果进行过滤 df = df[['num_yes', 'something1', 'something']] # SELECT, 选择要显示的列 df.sort_values('sometthing', ascending=True)[:30] # ORDER BY 和 LIMIT df[:30]
这样写并不是因为 pandas 规定了这些规则,而是按照JOIN/WHERE/GROUP BY/HAVING 这样的顺序来写代码会更有意义些。不过我经常会先写 WHERE 来改进性能,而且我想大多数数据库引擎也会这么做。
R 语言里的 dplyr 也允许开发人员使用不同的语法编写 SQL 查询语句,用来查询 Postgre、MySQL 和 SQLite。 本文地址: https://www.linuxprobe.com/select-sql.html
系统运维
2019-11-30 11:38:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
类似于执行:ansible all -m setup cat 1.py #!/usr/bin/env python #coding=utf-8 #------------------------------------------模块的导入----------------------------------------------- import json import shutil from ansible.module_utils.common.collections import ImmutableDict from ansible.parsing.dataloader import DataLoader from ansible.vars.manager import VariableManager from ansible.inventory.manager import InventoryManager from ansible.playbook.play import Play from ansible.executor.task_queue_manager import TaskQueueManager from ansible.plugins.callback import CallbackBase from ansible import context import ansible.constants as C #类-------------------------------------------继承CallbackBase类------------------------------------ class ResultCallback(CallbackBase): def v2_runner_on_ok(self, result, **kwargs): host = result._host #该主机信息:result._host #运行的是那个任务名称:result.task_name #运行的结果:result._result #正对哪个主机:host.name #这里打印针对哪个主机,结果是什么 print(json.dumps({host.name: result._result}, indent=4)) #'这里可对返回结果进行截取重组' #----------------------------------------无需修改内容---------------------------------------------- #smart表示执行远程命令,forks表示并发 context.CLIARGS = ImmutableDict(connection='local', module_path=[], forks=10, become=None, become_method=None, become_user=None, check=False, diff=False) #加载数据的类,加载剧本等 loader = DataLoader() #切换用户的密码,剧本加密等 #passwords = dict(vault_pass='secret') passwords={} #实例化 results_callback = ResultCallback() #剧本管理,sources指定剧本路径 inventory = InventoryManager(loader=loader, sources='localhost,') #对剧本中的变量进行管理 variable_manager = VariableManager(loader=loader, inventory=inventory) #-------------------------------------需要修改的内容:-------------------------------------------------- #重要,tasks里面编写任务,ansible all -i etc/ansbile/hosts -m setup play_source = { 'name':"test",#剧本名称 'hosts':'all', #剧本hosts,在那些主机上执行 'gather_facts': 'no', #关闭执行剧本前对所以机器信息的收集 'tasks' :[ #列表可执行多个任务,name表示任务名称,setup表示模板名称 { 'name':'fact','setup':''}, ] } #----------------------------------------回调----------------------------------------------- #任务装载执行那个play,任务变量有哪些 play = Play().load(play_source, variable_manager=variable_manager, loader=loader) tqm = None try: #定义任务管理器,传入剧本,变量等 tqm = TaskQueueManager( inventory=inventory,#剧本 variable_manager=variable_manager,#变量 loader=loader, passwords=passwords, stdout_callback=results_callback, #回调 ) result = tqm.run(play) #运行剧本 finally: #执行完成后任务清理后台临时数据 if tqm is not None: tqm.cleanup() shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
执行结果:python 1.py 127.0.0.1 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "172.17.0.1", "172.16.235.11" ], "ansible_all_ipv6_addresses": [], "ansible_apparmor": { "status": "disabled" }, "ansible_architecture": "x86_64", "ansible_bios_date": "04/01/2014", "ansible_bios_version": "3288b3c", "ansible_cmdline": { "BOOT_IMAGE": "/boot/vmlinuz-3.10.0-957.21.3.el7.x86_64", "LANG": "en_US.UTF-8", "biosdevname": "0", "console": "ttyS0,115200n8", "crashkernel": "auto", "idle": "halt", "net.ifnames": "0", "noibrs": true, "quiet": true, "rhgb": true, "ro": true, "root": "UUID=1114fe9e-2309-4580-b183-d778e6d97397" }, "ansible_date_time": { "date": "2019-11-29", "day": "29", "epoch": "1575028422", "hour": "19", "iso8601": "2019-11-29T11:53:42Z", "iso8601_basic": "20191129T195342834656", "iso8601_basic_short": "20191129T195342", "iso8601_micro": "2019-11-29T11:53:42.834755Z", "minute": "53", "month": "11", "second": "42", "time": "19:53:42", "tz": "CST", "tz_offset": "+0800", "weekday": "Friday", "weekday_number": "5", "weeknumber": "47", "year": "2019" }, "ansible_default_ipv4": { "address": "172.16.235.11", "alias": "eth0", "broadcast": "172.16.239.255", "gateway": "172.16.239.253", "interface": "eth0", "macaddress": "00:16:3e:11:9b:be", "mtu": 1500, "netmask": "255.255.240.0", "network": "172.16.224.0", "type": "ether" }, "ansible_default_ipv6": {}, "ansible_device_links": { "ids": {}, "labels": {}, "masters": {}, "uuids": { "vda1": [ "1114fe9e-2309-4580-b183-d778e6d97397" ] } }, "ansible_devices": { "vda": { "holders": [], "host": "SCSI storage controller: Red Hat, Inc. Virtio block device", "links": { "ids": [], "labels": [], "masters": [], "uuids": [] }, "model": null, "partitions": { "vda1": { "holders": [], "links": { "ids": [], "labels": [], "masters": [], "uuids": [ "1114fe9e-2309-4580-b183-d778e6d97397" ] }, "sectors": "83873317", "sectorsize": 512, "size": "39.99 GB", "start": "2048", "uuid": "1114fe9e-2309-4580-b183-d778e6d97397" } }, "removable": "0", "rotational": "1", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "mq-deadline", "sectors": "83886080", "sectorsize": "512", "size": "40.00 GB", "support_discard": "0", "vendor": "0x1af4", "virtual": 1 } }, "ansible_distribution": "CentOS", "ansible_distribution_file_parsed": true, "ansible_distribution_file_path": "/etc/redhat-release", "ansible_distribution_file_variety": "RedHat", "ansible_distribution_major_version": "7", "ansible_distribution_release": "Core", "ansible_distribution_version": "7.6", "ansible_dns": { "nameservers": [ "100.100.2.136", "100.100.2.138" ], "options": { "attempts": "3", "rotate": true, "single-request-reopen": true, "timeout": "2" } }, "ansible_docker0": { "active": true, "device": "docker0", "features": { "busy_poll": "off [fixed]", "fcoe_mtu": "off [fixed]", "generic_receive_offload": "on", "generic_segmentation_offload": "on", "highdma": "on", "hw_tc_offload": "off [fixed]", "l2_fwd_offload": "off [fixed]", "large_receive_offload": "off [fixed]", "loopback": "off [fixed]", "netns_local": "on [fixed]", "ntuple_filters": "off [fixed]", "receive_hashing": "off [fixed]", "rx_all": "off [fixed]", "rx_checksumming": "off [fixed]", "rx_fcs": "off [fixed]", "rx_gro_hw": "off [fixed]", "rx_udp_tunnel_port_offload": "off [fixed]", "rx_vlan_filter": "off [fixed]", "rx_vlan_offload": "off [fixed]", "rx_vlan_stag_filter": "off [fixed]", "rx_vlan_stag_hw_parse": "off [fixed]", "scatter_gather": "on", "tcp_segmentation_offload": "on", "tx_checksum_fcoe_crc": "off [fixed]", "tx_checksum_ip_generic": "on", "tx_checksum_ipv4": "off [fixed]", "tx_checksum_ipv6": "off [fixed]", "tx_checksum_sctp": "off [fixed]", "tx_checksumming": "on", "tx_fcoe_segmentation": "off [requested on]", "tx_gre_csum_segmentation": "on", "tx_gre_segmentation": "on", "tx_gso_partial": "on", "tx_gso_robust": "off [requested on]", "tx_ipip_segmentation": "on", "tx_lockless": "on [fixed]", "tx_nocache_copy": "off", "tx_scatter_gather": "on", "tx_scatter_gather_fraglist": "on", "tx_sctp_segmentation": "on", "tx_sit_segmentation": "on", "tx_tcp6_segmentation": "on", "tx_tcp_ecn_segmentation": "on", "tx_tcp_mangleid_segmentation": "on", "tx_tcp_segmentation": "on", "tx_udp_tnl_csum_segmentation": "on", "tx_udp_tnl_segmentation": "on", "tx_vlan_offload": "on", "tx_vlan_stag_hw_insert": "on", "udp_fragmentation_offload": "on", "vlan_challenged": "off [fixed]" }, "hw_timestamp_filters": [], "id": "8000.0242e36a5228", "interfaces": [ "vethd3a18be" ], "ipv4": { "address": "172.17.0.1", "broadcast": "172.17.255.255", "netmask": "255.255.0.0", "network": "172.17.0.0" }, "macaddress": "02:42:e3:6a:52:28", "mtu": 1500, "promisc": false, "stp": false, "timestamping": [ "rx_software", "software" ], "type": "bridge" }, "ansible_domain": "", "ansible_effective_group_id": 0, "ansible_effective_user_id": 0, "ansible_env": { "HOME": "/root", "LANG": "en_US.UTF-8", "LESSOPEN": "||/usr/bin/lesspipe.sh %s", "LOGNAME": "root", "LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:", "MAIL": "/var/mail/root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", "PWD": "/root", "SHELL": "/bin/bash", "SHLVL": "2", "SSH_CLIENT": "127.0.0.1 57402 22", "SSH_CONNECTION": "127.0.0.1 57402 127.0.0.1 22", "SSH_TTY": "/dev/pts/4", "TERM": "xterm", "USER": "root", "XDG_RUNTIME_DIR": "/run/user/0", "XDG_SESSION_ID": "16616", "_": "/usr/bin/python" }, "ansible_eth0": { "active": true, "device": "eth0", "features": { "busy_poll": "off [fixed]", "fcoe_mtu": "off [fixed]", "generic_receive_offload": "on", "generic_segmentation_offload": "on", "highdma": "on [fixed]", "hw_tc_offload": "off [fixed]", "l2_fwd_offload": "off [fixed]", "large_receive_offload": "off [fixed]", "loopback": "off [fixed]", "netns_local": "off [fixed]", "ntuple_filters": "off [fixed]", "receive_hashing": "off [fixed]", "rx_all": "off [fixed]", "rx_checksumming": "on [fixed]", "rx_fcs": "off [fixed]", "rx_gro_hw": "off [fixed]", "rx_udp_tunnel_port_offload": "off [fixed]", "rx_vlan_filter": "on [fixed]", "rx_vlan_offload": "off [fixed]", "rx_vlan_stag_filter": "off [fixed]", "rx_vlan_stag_hw_parse": "off [fixed]", "scatter_gather": "on", "tcp_segmentation_offload": "on", "tx_checksum_fcoe_crc": "off [fixed]", "tx_checksum_ip_generic": "on", "tx_checksum_ipv4": "off [fixed]", "tx_checksum_ipv6": "off [fixed]", "tx_checksum_sctp": "off [fixed]", "tx_checksumming": "on", "tx_fcoe_segmentation": "off [fixed]", "tx_gre_csum_segmentation": "off [fixed]", "tx_gre_segmentation": "off [fixed]", "tx_gso_partial": "off [fixed]", "tx_gso_robust": "off [fixed]", "tx_ipip_segmentation": "off [fixed]", "tx_lockless": "off [fixed]", "tx_nocache_copy": "off", "tx_scatter_gather": "on", "tx_scatter_gather_fraglist": "off [fixed]", "tx_sctp_segmentation": "off [fixed]", "tx_sit_segmentation": "off [fixed]", "tx_tcp6_segmentation": "on", "tx_tcp_ecn_segmentation": "on", "tx_tcp_mangleid_segmentation": "off", "tx_tcp_segmentation": "on", "tx_udp_tnl_csum_segmentation": "off [fixed]", "tx_udp_tnl_segmentation": "off [fixed]", "tx_vlan_offload": "off [fixed]", "tx_vlan_stag_hw_insert": "off [fixed]", "udp_fragmentation_offload": "on", "vlan_challenged": "off [fixed]" }, "hw_timestamp_filters": [], "ipv4": { "address": "172.16.235.11", "broadcast": "172.16.239.255", "netmask": "255.255.240.0", "network": "172.16.224.0" }, "macaddress": "00:16:3e:11:9b:be", "module": "virtio_net", "mtu": 1500, "pciid": "virtio0", "promisc": false, "timestamping": [ "rx_software", "software" ], "type": "ether" }, "ansible_fibre_channel_wwn": [], "ansible_fips": false, "ansible_form_factor": "Other", "ansible_fqdn": "iZbp198ltire1iou0oamr0Z", "ansible_hostname": "bestyunyan", "ansible_hostnqn": "", "ansible_interfaces": [ "lo", "vethd3a18be", "docker0", "eth0" ], "ansible_is_chroot": false, "ansible_iscsi_iqn": "", "ansible_kernel": "3.10.0-957.21.3.el7.x86_64", "ansible_kernel_version": "#1 SMP Tue Jun 18 16:35:19 UTC 2019", "ansible_lo": { "active": true, "device": "lo", "features": { "busy_poll": "off [fixed]", "fcoe_mtu": "off [fixed]", "generic_receive_offload": "on", "generic_segmentation_offload": "on", "highdma": "on [fixed]", "hw_tc_offload": "off [fixed]", "l2_fwd_offload": "off [fixed]", "large_receive_offload": "off [fixed]", "loopback": "on [fixed]", "netns_local": "on [fixed]", "ntuple_filters": "off [fixed]", "receive_hashing": "off [fixed]", "rx_all": "off [fixed]", "rx_checksumming": "on [fixed]", "rx_fcs": "off [fixed]", "rx_gro_hw": "off [fixed]", "rx_udp_tunnel_port_offload": "off [fixed]", "rx_vlan_filter": "off [fixed]", "rx_vlan_offload": "off [fixed]", "rx_vlan_stag_filter": "off [fixed]", "rx_vlan_stag_hw_parse": "off [fixed]", "scatter_gather": "on", "tcp_segmentation_offload": "on", "tx_checksum_fcoe_crc": "off [fixed]", "tx_checksum_ip_generic": "on [fixed]", "tx_checksum_ipv4": "off [fixed]", "tx_checksum_ipv6": "off [fixed]", "tx_checksum_sctp": "on [fixed]", "tx_checksumming": "on", "tx_fcoe_segmentation": "off [fixed]", "tx_gre_csum_segmentation": "off [fixed]", "tx_gre_segmentation": "off [fixed]", "tx_gso_partial": "off [fixed]", "tx_gso_robust": "off [fixed]", "tx_ipip_segmentation": "off [fixed]", "tx_lockless": "on [fixed]", "tx_nocache_copy": "off [fixed]", "tx_scatter_gather": "on [fixed]", "tx_scatter_gather_fraglist": "on [fixed]", "tx_sctp_segmentation": "on", "tx_sit_segmentation": "off [fixed]", "tx_tcp6_segmentation": "on", "tx_tcp_ecn_segmentation": "on", "tx_tcp_mangleid_segmentation": "on", "tx_tcp_segmentation": "on", "tx_udp_tnl_csum_segmentation": "off [fixed]", "tx_udp_tnl_segmentation": "off [fixed]", "tx_vlan_offload": "off [fixed]", "tx_vlan_stag_hw_insert": "off [fixed]", "udp_fragmentation_offload": "on", "vlan_challenged": "on [fixed]" }, "hw_timestamp_filters": [], "ipv4": { "address": "127.0.0.1", "broadcast": "host", "netmask": "255.0.0.0", "network": "127.0.0.0" }, "mtu": 65536, "promisc": false, "timestamping": [ "rx_software", "software" ], "type": "loopback" }, "ansible_local": {}, "ansible_lsb": { "codename": "Core", "description": "CentOS Linux release 7.6.1810 (Core)", "id": "CentOS", "major_release": "7", "release": "7.6.1810" }, "ansible_lvm": { "lvs": {}, "pvs": {}, "vgs": {} }, "ansible_machine": "x86_64", "ansible_machine_id": "20190711105006363114529432776998", "ansible_memfree_mb": 161, "ansible_memory_mb": { "nocache": { "free": 1095, "used": 743 }, "real": { "free": 161, "total": 1838, "used": 1677 }, "swap": { "cached": 0, "free": 0, "total": 0, "used": 0 } }, "ansible_memtotal_mb": 1838, "ansible_mounts": [ { "block_available": 8739277, "block_size": 4096, "block_total": 10286868, "block_used": 1547591, "device": "/dev/vda1", "fstype": "ext4", "inode_available": 2466821, "inode_total": 2621440, "inode_used": 154619, "mount": "/", "options": "rw,relatime,data=ordered", "size_available": 35796078592, "size_total": 42135011328, "uuid": "1114fe9e-2309-4580-b183-d778e6d97397" } ], "ansible_nodename": "bestyunyan", "ansible_os_family": "RedHat", "ansible_pkg_mgr": "yum", "ansible_proc_cmdline": { "BOOT_IMAGE": "/boot/vmlinuz-3.10.0-957.21.3.el7.x86_64", "LANG": "en_US.UTF-8", "biosdevname": "0", "console": [ "tty0", "ttyS0,115200n8" ], "crashkernel": "auto", "idle": "halt", "net.ifnames": "0", "noibrs": true, "quiet": true, "rhgb": true, "ro": true, "root": "UUID=1114fe9e-2309-4580-b183-d778e6d97397" }, "ansible_processor": [ "0", "GenuineIntel", "Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz" ], "ansible_processor_cores": 1, "ansible_processor_count": 1, "ansible_processor_threads_per_core": 1, "ansible_processor_vcpus": 1, "ansible_product_name": "Alibaba Cloud ECS", "ansible_product_serial": "0c7a1379-554a-41c2-80de-51d44832d08e", "ansible_product_uuid": "0C7A1379-554A-41C2-80DE-51D44832D08E", "ansible_product_version": "pc-i440fx-2.1", "ansible_python": { "executable": "/usr/bin/python", "has_sslcontext": true, "type": "CPython", "version": { "major": 2, "micro": 5, "minor": 7, "releaselevel": "final", "serial": 0 }, "version_info": [ 2, 7, 5, "final", 0 ] }, "ansible_python_version": "2.7.5", "ansible_real_group_id": 0, "ansible_real_user_id": 0, "ansible_selinux": { "status": "disabled" }, "ansible_selinux_python_present": true, "ansible_service_mgr": "systemd", "ansible_ssh_host_key_dsa_public": "AAAAB3NzaC1kc3MAAACBAJd+s+jOekl4ScPJpTnbT2JC8LjfYrbDCoz0L4c0N6cN+oWbLFR4/Q5RqrVmpZAjRIiXKZfk1y6TIdderbJJshxzvYgc8OJDH7/IgvDzTAlSCPc5T14RMl6Bhrp0vIg4EiMkUhCTgdawjjfV4FUJoKnPwW+d39A5ripOEUYWEJv7AAAAFQCacs4SkpudSFTE5R3k5sHVZFGLaQAAAIAoPI2Pn/UsMHcf2o6FdfQea5nhzzV/Xg/tGBlAzASJ68jMit3vjoyfPvO4P61p3mIS6e3pREeODE6dlADKPbTF8YXkbfXo544cL8RuEI2AGT7UU1wYJNBVQ/y19EJGSiQRLE+QLnizJ69Ce20Ja2mD1uuAp8eiBvcyl4byRfi2nQAAAIAYmlJMFtWu+0bOHc5eYynlnHmGn9l8w3muxlG9g/WB1CPxMczCwHlMqRgxOyM0DUjkDYycGddBqHdwlAu/oVSxSut6GzDHjzwGcK1pPlnqwnFyAiT2oMOX6F1HmZlYeJVSORbIavWMu5evO5DYnCdR4p04x98nE6i7YwYWI+xQ+A==", "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPmNBvDALEOFEmP9uj+gSxswdpsbhEdCLyUTHktwiwTApcMY/hQjxcE+C5GnuRY2lctaLh64h94eKrk59gKZ8+8=", "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIGkZLb2ZJI1Moi1Uezq6Q/rEadasfyxSiV6dxgS0wQ7F", "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDLj4NA2pfWvJf66ucT00Qfn1dyafGlkAe1Src5IfQwY74zUTc5awVhr7iNZn3hJO35m63e8QFJxkeaxe/XDz+sklipJbcuhfDtpFG3sXps+6A08pAdQSPQvj3JRJrow7U0YS9ctpD0sSUjov+xtMMvDEVj92H99EvhkaTUUpqXwWXKkycN5D6hpEE7aIPNHaCy/dYlrZimQitMmuGxbaP5is41FxIM2BkrfL7ZBx4LhilpOHUNRas14OW4sZTHbLUolA2cdRgXs67Y+F9mtVTN0WlyInvw8kuMrMwWeNQ41m2LkY4Vlnvh3nAiPn/xnEmsQw8/5k4utQoAfHFoG4GL", "ansible_swapfree_mb": 0, "ansible_swaptotal_mb": 0, "ansible_system": "Linux", "ansible_system_capabilities": [ "cap_chown", "cap_dac_override", "cap_dac_read_search", "cap_fowner", "cap_fsetid", "cap_kill", "cap_setgid", "cap_setuid", "cap_setpcap", "cap_linux_immutable", "cap_net_bind_service", "cap_net_broadcast", "cap_net_admin", "cap_net_raw", "cap_ipc_lock", "cap_ipc_owner", "cap_sys_module", "cap_sys_rawio", "cap_sys_chroot", "cap_sys_ptrace", "cap_sys_pacct", "cap_sys_admin", "cap_sys_boot", "cap_sys_nice", "cap_sys_resource", "cap_sys_time", "cap_sys_tty_config", "cap_mknod", "cap_lease", "cap_audit_write", "cap_audit_control", "cap_setfcap", "cap_mac_override", "cap_mac_admin", "cap_syslog", "35", "36+ep" ], "ansible_system_capabilities_enforced": "True", "ansible_system_vendor": "Alibaba Cloud", "ansible_uptime_seconds": 8477706, "ansible_user_dir": "/root", "ansible_user_gecos": "root", "ansible_user_gid": 0, "ansible_user_id": "root", "ansible_user_shell": "/bin/bash", "ansible_user_uid": 0, "ansible_userspace_architecture": "x86_64", "ansible_userspace_bits": "64", "ansible_vethd3a18be": { "active": true, "device": "vethd3a18be", "features": { "busy_poll": "off [fixed]", "fcoe_mtu": "off [fixed]", "generic_receive_offload": "on", "generic_segmentation_offload": "on", "highdma": "on", "hw_tc_offload": "off [fixed]", "l2_fwd_offload": "off [fixed]", "large_receive_offload": "off [fixed]", "loopback": "off [fixed]", "netns_local": "off [fixed]", "ntuple_filters": "off [fixed]", "receive_hashing": "off [fixed]", "rx_all": "off [fixed]", "rx_checksumming": "on", "rx_fcs": "off [fixed]", "rx_gro_hw": "off [fixed]", "rx_udp_tunnel_port_offload": "off [fixed]", "rx_vlan_filter": "off [fixed]", "rx_vlan_offload": "on", "rx_vlan_stag_filter": "off [fixed]", "rx_vlan_stag_hw_parse": "on", "scatter_gather": "on", "tcp_segmentation_offload": "on", "tx_checksum_fcoe_crc": "off [fixed]", "tx_checksum_ip_generic": "on", "tx_checksum_ipv4": "off [fixed]", "tx_checksum_ipv6": "off [fixed]", "tx_checksum_sctp": "on", "tx_checksumming": "on", "tx_fcoe_segmentation": "off [fixed]", "tx_gre_csum_segmentation": "on", "tx_gre_segmentation": "on", "tx_gso_partial": "off [fixed]", "tx_gso_robust": "off [fixed]", "tx_ipip_segmentation": "on", "tx_lockless": "on [fixed]", "tx_nocache_copy": "off", "tx_scatter_gather": "on", "tx_scatter_gather_fraglist": "on", "tx_sctp_segmentation": "on", "tx_sit_segmentation": "on", "tx_tcp6_segmentation": "on", "tx_tcp_ecn_segmentation": "on", "tx_tcp_mangleid_segmentation": "on", "tx_tcp_segmentation": "on", "tx_udp_tnl_csum_segmentation": "on", "tx_udp_tnl_segmentation": "on", "tx_vlan_offload": "on", "tx_vlan_stag_hw_insert": "on", "udp_fragmentation_offload": "on", "vlan_challenged": "off [fixed]" }, "hw_timestamp_filters": [], "macaddress": "52:1f:ac:1d:5f:df", "mtu": 1500, "promisc": true, "speed": 10000, "timestamping": [ "rx_software", "software" ], "type": "ether" }, "ansible_virtualization_role": "guest", "ansible_virtualization_type": "kvm", "discovered_interpreter_python": "/usr/bin/python", "gather_subset": [ "all" ], "module_setup": true }, "changed": false }
系统运维
2019-11-29 19:53:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
gitlab的备份 #!/bin/bash RED_COLOR='\E[1;31m' RES='\E[0m' backup_Time=`date "+%Y_%m_%d"` ###backupGitLab /opt/gitlab/bin/gitlab-rake gitlab:backup:create if [[ $? -eq 0 ]]; then echo -e "${RED_COLOR}备份成功${RES}" ###sendFile ##备份到远端主机 #sudo rsync -avz --ignore-existing /var/opt/gitlab/backups/ root@10.0.0.0:/var/opt/gitlab/backups/ #rsync -avzP --delete /var/opt/gitlab/backups/ 10.0.0.0:/data/gitlab_data_backup/ #rsync -av /var/opt/gitlab/backups/ 10.0.0.0:/data/gitlab_data_backup/ #rsync -aq /data/shell/ 10.0.0.0:/data/gitlab_data_backup/ # if [[ $? -eq 0 ]]; then # echo -e "${RED_COLOR}发送成功${RES}" # else # echo -e "${RED_COLOR}发送失败${RES}" # fi else echo -e "${RED_COLOR}备份失败${RES}" exit 1; fi ##删除三天前的备份 find "/backup/backups" -name "*.tar" -ctime +3 -exec rm -rf {} \; if [[ $? -eq 0 ]]; then echo -e "${RED_COLOR}删除备份成功${RES}" else echo -e "${RED_COLOR}删除备份失败${RES}" fi
gitlab的还原 gitlab崩溃将数据恢复到对应新的服务器中 1、yum install gitlab-ee-10.2.5-ee.0.el7 安装相关版本的gitlab 2、gitlab-ctl reconfigure 初始化gitlab,方能正常使用 3、执行gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq 停掉相关服务 4、执行恢复命令 gitlab-rake gitlab:backup:restore BACKUP=1550988551_2019_02_24_10.2.5-ee(类似) 恢复过程中需要输入几个yes, 5、完成后执行gitlab-ctl restart重启,如果一切正常将域名解析到新服务器
系统运维
2019-11-29 17:04:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
尝试
1、通过du -sh 无法无法找到大文件目录
2、通过lsof |grep "deleted" 无法找到 标记为 deleted的进程
手动卸载 系统上挂载的目录 发现卸载后的目录里面有大文件 根还是没有释放空间 原来这个目录有文件 又被挂载到这个目录下。
解决办法 1、卸载Oracledata目录
2、删除原来目录下的文件
3、重新挂载现在的目录解决
有时候有的文件夹还没挂载之前就已经在使用了,并且占用一定的空间,当再次用新的分区挂载到这个目录下的时候,原来的文件就会被隐藏。所以在分析系统空间的时候,最好把所有单独挂载的分区都卸载掉来分析。
系统运维
2019-11-28 12:02:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
你想知道如何用mac来屏蔽网址,跟着下面的步骤学,你就能学会。
Mac电脑下面Dock工具栏,鼠标右键点击访达,如下图所示。

接着 弹出的输入框中输入,/private/etc/
然后右键把host@s这个文件拷贝到电脑桌面,右键文本编辑打开。
末尾输入要屏蔽的域名,如下图例子所示。
然后保存, 接着拖到原来的位置替换之前的host@s那个文件就行了 本文地址: https://www.linuxprobe.com/mac-website-use.html
系统运维
2019-11-28 11:09:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
在 mac 下 phpize编译扩展时,出现如下报错: /usr/bin/ phpize Configuring for: PHP Api Version: 20121113 Zend Module Api No: 20121212 Zend Extension Api No: 220121212 Cannot find autoconf . Please check your autoconf installation and the $PHP_AUTOCONF environment variable. Then, rerun this script.
解决办法也简单,在终端中运行如下命令: $ brew install autoconf
如果 Homebrew 未安装,可先参考: Homebrew 套件管理器使 Mac OS X 更完美 $ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
Buy me a cup of coffee :)
系统运维
2019-11-28 10:32:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
1.下载
打开官网: https://redis.io/
Download---Stable---Download3.2.8,下载最新稳定版,这里是3.2.8
2.安装
下载完成后,打开命令行工具,执行解压命令 tar zxvf redis-3.2.8.tar.gz

将解压后文件夹放到/usr/local mv redis-3.2.8 /usr/local/
切换到相应目录 cd /usr/local/redis-3.2.8/
编译测试 sudo make test

编译安装 sudo make install
启动Redis redis-server
3.配置
在redis目录下建立bin,etc,db三个目录 sudo mkdir /usr/local/redis-3.2.8/bin sudo mkdir /usr/local/redis-3.2.8/etc sudo mkdir /usr/local/redis-3.2.8/db
把/usr/local/redis/src目录下的mkreleasehdr.sh,redis-benchmark, redis-check-rdb, redis-cli, redis-server拷贝到bin目录 cp /usr/local/redis-3.2.8/src/mkreleasehdr.sh . cp /usr/local/redis-3.2.8/src/redis-benchmark . cp /usr/local/redis-3.2.8/src/redis-check-rdb . cp /usr/local/redis-3.2.8/src/redis-cli . cp /usr/local/redis-3.2.8/src/redis-server .
拷贝 redis.conf 到 /usr/local/redis/etc下 cp /usr/local/redis-3.2.8/redis.conf /usr/local/redis-3.2.8/etc
修改redis.conf #修改为守护模式 daemonize yes #设置进程锁文件 pidfile /usr/local/redis-3.2.8/redis.pid #端口 port 6379 #客户端超时时间 timeout 300 #日志级别 loglevel debug #日志文件位置 logfile /usr/local/redis-3.2.8/log-redis.log #设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id databases 16 ##指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 #save #Redis默认配置文件中提供了三个条件: save 900 1 save 300 10 save 60 10000 #指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间, #可以关闭该#选项,但会导致数据库文件变的巨大 rdbcompression yes #指定本地数据库文件名 dbfilename dump.rdb #指定本地数据库路径 dir /usr/local/redis-3.2.8/db/ #指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能 #会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有 #的数据会在一段时间内只存在于内存中 appendonly no #指定更新日志条件,共有3个可选值: #no:表示等操作系统进行数据缓存同步到磁盘(快) #always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全) #everysec:表示每秒同步一次(折衷,默认值) appendfsync everysec
启动服务 ./bin/redis-server etc/redis.conf
查看日志 tail -f log-redis.log
打开redis客户端 ./bin/redis-cli
执行redis命令
尽情操作吧。
Buy me a cup of coffee :)
系统运维
2019-11-28 10:20:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
一、概述
在Openstack的虚拟机中的平台系统,原来20G的硬盘容量不足,需要扩容到48G。原来的硬盘方案是一个分区(root分区), 无交换分区,分区没有使用LVM, 不能利用LVM进行扩容。
在现有的基础上进行扩容,大致思路是:
1) 以正在运行的虚拟机为模板创建快照;
2) 以新快照新建云硬盘,调整硬盘大小到48G;
3) 将新云硬盘挂载到一台虚拟机中,重新分区,扩展分区大小;
4) 将扩展后的云硬盘上传到镜像中;
5) 以新镜像为模板创建新虚拟机。
二、扩容方案
2.1 创建快照
2.2 新建云硬盘(以30G为例)
2.3 扩展分区大小(重要:这一步操作危险性高,容易造成分区表丢失,原有数据丢失)
(1) 将新硬盘挂载到虚拟机中

(2) 登录到虚拟机,开始扩展硬盘分区
查看新挂载硬盘的分区情况, 记住分区的起止柱面数
第1步:先删掉原来的分区
第2步:重建分区,并保存分区
注意: 起始柱面一定要与原来的一致,这里要扩展到整个硬盘,终止柱面选默认值。
第3步: 重新定义文件系统
# e2fsck -f /dev/vdb1
# resize2fs /dev/vdb1
第4步: 检查新硬盘
# mount /dev/vdb1 /mnt
可以看到磁盘已扩容
2.4 将新云硬盘上传到镜像中
将新硬盘从虚拟机中卸载
上传到镜像
2.5 以新镜像创建虚拟机
三、收尾
将操作过程中新建的快照 , 云硬盘删除。
系统运维
2019-11-28 09:58:00
「深度学习福利」大神带你进阶工程师,立即查看>>> Config Server是干嘛的 配置服务器保留有所有分片节点的元数据,这些元数据包括所有分片节点状态,副本节点的组织结构以及副本节点数据存储位置。
元数据包括,每个分片节点的chunk信息以及这些chunk对应的range区间定义。
通过这些数据将读写操作正确的路由到对应的分片节点上。
如果集群的元数据信息变化,管理程序mongod将会进行更新操作:chunk分裂,添加分片节点。
分片节点同样需要从配置服务器读取这些数据。
配置服务器同样保存授权信息,比如:用户访问授权,和内部授权等。
使用配置服务器来管理分布式锁机制。
每一个分片集群都应该有自己的配置服务器,不要使用多个集群使用同一个。
授权操作可能会影响到分片节点的性能和使用,如果配置服务器被影响的数量较多,可能会导致分片节点仅仅只能进行读操作,或者是下线一段时间。 配置服务器副本集 以前mongo是使用镜像快照的方式进行备份。
配置服务器可以使用分片节点副本集机制来提高配置服务间的同步性能。
因为有多副本配置服务器,所以可以允许不同的分片节点选择访问某一个配置服务器,形成了n:m的格局,而不是1:1,减轻了压力,也提高了性能。
副本集配置服务器有如下三原则: 不能有决策者。 不能有短板成员,(延迟高)。 必须创建索引。 配置服务器的读写操作 admin数据库保存着授权和认证,和其他的数据库系统的system数据库一样。
配置服务器分片节点集群的数据,当分片节点发生了如chunk块迁移或者分裂的时候会向主服务器写入数据。
用户应该尽量避免直接操作配置服务器,而 应该通过触发操作来修改。
系统运维
2019-11-29 16:13:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
Kubernetes改变了我们所有人对计算平台的看法。我们同样也需要改变现代应用程序存储数据的方式。企业越来越多地依赖数字服务来接触客户,传统企业正在Kubernetes上重新部署它们的IT应用和服务。容器的可移植性和Kubernetes自动化的好处意味着在整个IT开发/测试和生产生命周期中我们可以更快、更可靠地交付应用程序。与此同时,企业必须认识到多云部署不仅仅是一种供应策略,而且还是一种对客户最合理的应用程序交付方式。
传统的存储行业还没有做好足够的工作来解决K8S的问题:容器可移植性、K8S自动化和多云交付。 Portworx企业版首先为K8S中大数据量的工作负载提供无缝的高可用性,无论这些工作负载是在本地系统还是在公共云中运行,都将提供无缝的高可用性。通过Portworx,开发团队可以获得集成调度程序、完整的数据生命周期管理,以及核心生产功能,如BYOK加密和云备份。
通过与那些已经把应用部署在主要的公有云平台或自有硬件平台上的优秀客户合作,Portworx已经掌握了完整的数据可迁移性、操作自动化、以及将含有大量数据的应用交付到多云部署中的真正能力。
可迁移性和易操作性
通过控制与K8S的集成方式,PX-Motion为大量数据型工作负载带来了充分的可迁移性。现在,类似Kubernetes为无状态工作负载带来的方便一样,我们在有状态工作负载上为客户的数据库、分析堆栈、机器学习和其他类型的应用提供数据服务。 只需一个命令,PX-Motion就可以跨集群和跨云移动K8S应用程序、Kubernetes配置和Portworx数据卷。
PX-Motion的功能有: 扩展容量 :将较低优先级的应用程序转移到次要集群,为关键集群释放容量。 蓝绿部署 :通过应用程序和数据来测试新版本的Kubernetes和Portworx。这一方法同云原生应用程序团队使用蓝绿部署法相同——现在你也可以将它用于您的容器基础架构。 清洁安装 :从Kubernetes到Portworx的每一个基础架构安装都是全新安装,而不是就地升级。无论是本地部署还是在公有云中,全新安装提供了一种更稳定的基础架构。 Dev/test :以自动化的方式将工作负荷从dev升级到分段集群。因此,它消除了人工准备数据的过程(这些步骤会影响测试准确性)。 迁移 :将应用程序和数据从本地部署集群迁移到AWS、谷歌、Azure、IBM或其他地方的云托管Kubernetes集群。同时反过来也支持。 维护 :它可在几分钟内迁移整个集群的应用程序和数据,以方便执行硬件的维护服务。
PX-Motion支持跨集群和云迁移,而PX-Central提供了必要的可视性操作界面来管理和控制数据的迁移。管理员和应用程序团队可以在每个应用程序级别上可视化的调度、控制正在进行的迁移的应用状态。
不仅如此,PX-Central还从根本上简化了对量数据工作负荷的管理。通过使用PX-Central,客户可以跨越多个集群或云,来管理、监视和元数据服务。
PX-Central的主要功能有: 多集群管理GUI :为您的所有容器数据需求(包括跟踪容量、配置和监视)提供统一的管理界面。 集中配置和调度 :简单设置即可完成关键数据保护机制,包括使用PX-企业版 CloudSnap™完成快照和云中备份。 内置元数据服务 :在使用PX-企业版时,消除了客户自己处理etcd服务的繁琐,并使集群更加易于管理。 主动监控 :已经为跟踪和分析指标、警报和异常进行了配置,让团队在规模化配置上更有效地操作。
系统运维
2019-11-29 15:09:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
同事建了一台做分布式存储服务器,刚开始是做测试,可能当时没有及时关闭root密码登录 & 开启密钥登录以及监控方面也没有做好.
导致被黑客扫到了密码,并与服务器做了免密钥登录,相当于黑客拿到了root用户 & 权限,在服务器上跑了木马.
本人会不定时去后台查看服务器 CPU 内存 I/O等的使用率,发现这台分布式存储服务器CPU 长期处于100%,就进入服务器看了一下,果然有三个人不明的进程.
Step 1. top 查看
说明:可见三个异常进程:Donald xfygfa4 xfygfa5

Step 2. 查看登录记录(这个是异常IP:59.41.64.89) $ last root pts/3 113.111.185.67 Thu Nov 28 07:32 still logged in root pts/2 113.111.142.177 Thu Nov 28 07:28 - 08:04 (00:36) root pts/1 117.136.41.59 Thu Nov 28 07:23 still logged in root pts/1 117.136.41.59 Thu Nov 28 07:21 - 07:23 (00:01) root pts/0 113.111.185.67 Thu Nov 28 07:13 still logged in root pts/1 113.111.0.10 Thu Nov 28 04:34 - 07:20 (02:45) root pts/0 113.111.0.10 Thu Nov 28 04:31 - 05:56 (01:25) root pts/0 59.41.64.89 Sat Nov 23 09:47 - 11:58 (02:11)

Step 3.使用ps aux|grep 这个三个进程(Donald xfygfa4 xfygfa5 )所在路径 $ ls -lh /tmp/Donald -rwxr-xr-x. 1 root root 3.8M Nov 28 07:48 /tmp/Donald $ ls -lh /usr/bin/xfygfa4 $ ls -lh /usr/bin/xfygfa5
Step 4.接下来找漏洞
说明:发现这个密钥不是服务器的密钥,我就删掉了,但没两分钟这个密钥又重新出现了. $ less /root/.ssh/authorized_keys #ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfxLBb/eKbi0TVVULI8ILVtbv2iaGM+eZbZoCWcD3v/eF1B/VkHAC1YwIhfqkUYudwhxVfQzsOZYQmKyapWzgp3tBAxcl82Al++VQc36mf/XFnECHndJS1JZB429/w/Ao+KlASl/qzita61D2VsXyejIQIeYR7Ro+ztLSTXjx+70CvzgOae3oayunL/hGX8qORIkG5YR3R1Jefhxy1NhGxEd6GaR7fZA5QWGfM17IcSXi2Q876JL8U7Aq8cjQyN/kGT2jWiiQiOZzqbjVJVICiwk0KvtrTwppV6FLty/vdfhgyspR4WZMep41xxuBH5rBkEJO5lqbKJWatcaA8n9jR root@localhost
Step 5. 锁定/root/.ssh/authorized_keys /usr/bin /tmp 让其不能更新 $ chattr +i /root/.ssh/authorized_keys $ chattr +i /usr/bin $ chattr +i /tmp
Step 6. kill Donald xfygfa4 xfygfa5 这三个进程 $ kill -9 341 12051 7681
Step 7.可见CPU已经降下来
系统运维
2019-11-29 12:24:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
我在Nginx Web服务器后面安装了pentaho。我想做的是将我的/重定向到/ pentaho而不成功。这是我的虚拟主机文件: server { listen 80; server_name estrategia-bi.ddns.net; root /var/lib/tomcat7/webapps/pentaho; # rewrite ^(.*)$ $scheme://estrategia-bi.ddns.net/pentaho/Login; location / { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Server $host; } }
我尝试了不同的方法,例如: proxy_pass http://127.0.0.1:8080/pentaho/;
但这给了我一种空白或部分加载的页面。 rewrite ^(.*)$ $scheme://estrategia-bi.ddns.net/pentaho;
但这给了我一个服务器错误,例如网址不完整?
我不知道该怎么做。希望有人能帮助我。
问候!
此重写为我们工作: server { listen 80; server_name estrategia-bi.ddns.net; root /var/lib/tomcat7/webapps/pentaho; rewrite ^/$ /pentaho/ permanent; location / { proxy_pass http://localhost:8080/; } }
我们从来没有找到一种完全重定向所有内部url的方法-您放置在本地的东西无法做到这一点,我们尝试过的其他任何方法也不起作用。Pentaho似乎只是忽略标题。
但是,此重写将使您进入登录页面。登录后,由于某种原因,您将被重定向到 http:// localhost:8080 / pentaho / 。重新加载主页,您应该已登录,然后一切正常。 @markemus提到的问题源于将https反向代理到http。浏览器安全性将阻止加载混合内容。我终于可以使用以下配置使它正常工作。我此配置在端口443上包含https和证书,但在端口80和http或在NINNX中从80重定向到443时,它可以轻松工作。
NGINX: server { listen [::]:443 ssl; listen 443 ssl; server_name my.exampledomain.com; ssl_certificate /path/to/certificate ssl_certificate_key /path/to/key location /pentaho/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://localhost:8080/pentaho/; } }
修改pentaho-server / tomcat / conf / server.xml以匹配条目:
修改pentaho-server / pentaho-solutions / system / server.properties以匹配条目: fully-qualified-server-url=https://my.exampledomain.com/pentaho/
确保重新启动pentaho服务器和nginx
系统运维
2019-11-29 11:45:05
「深度学习福利」大神带你进阶工程师,立即查看>>>
1:使用之前,先通过Composer安装: composer require zgldh/qiniu-laravel-storage
如果执行过程中报以下错误:说明php没有开启扩展fileinfo,在php扩展开启fileinfo即可 Your requirements could not be resolved to an installable set of packages. Problem 1 - stevenyangecho/laravel-u-editor v1.4.2 requires ext-fileinfo * -> the requested PHP extension fileinfo is missing from your system. - stevenyangecho/laravel-u-editor v1.4.1 requires ext-fileinfo * -> the requested PHP extension fileinfo is missing from your system. - stevenyangecho/laravel-u-editor v1.4.0 requires ext-fileinfo * -> the requested PHP extension fileinfo is missing from your system. - Installation request for stevenyangecho/laravel-u-editor ~1.4 -> satisfiable by stevenyangecho/laravel-u-editor[v1.4.0, v1.4.1, v1.4.2]. To enable extensions, verify that they are enabled in your .ini files: - F:\phpStudy\PHPTutorial\php\php-7.2.1-nts\php.ini You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode. Installation failed, reverting ./composer.json to its original content.
2:然后在 config/app.php providers 中注册服务提供者:
zgldh\QiniuStorage\QiniuFilesystemServiceProvider::class
3:接下来在config/filesystems.php里的disks中新增如下选项: 'disks' => [ ... , 'qiniu' => [ 'driver' => 'qiniu', 'domains' => [ 'default' => 'xxxxx', //你的七牛域名 'https' => 'xxxxx',//你的HTTPS域名 'custom' => 'xxxxx',//你的自定义域名 ], 'access_key'=> 'IKYPvIRNQRxahzSzQh-9nf0er--4oTCzkeIWQM4X', //AccessKey 'secret_key'=> '3KfIusCaWrJGiJnR1kvX6y3UJ1CyBbDHVK7Nm1xi', //SecretKey 'bucket' => '1805a', //Bucket名字 'notify_url'=> 'http://www.zb.cn/lx', //持久化处理回调地址 ], ],
4: OK,扩展包的安装就暂时介绍到这里,接下来我们要去七牛注册一个账号并且将上面的配置完善。
七牛账号注册及配置
先去七牛注册一个账号,点击官网的注册会让我们选择用户类型,这里我就选择个人用户,接下来按照流程来进项注册就OK了.
点击秘钥管理,就可与看到个人七牛的秘钥了:
七牛在Laravel中的配置
上面已经介绍相关的配置在哪儿,现在我们要将这些配置在Laravel中使用:
先在 resources\views 下新建 image.blade.php 视图 上传图片

实现上传方法:控制器 isMethod('post')) { // 判断是否有文件上传 if ($request->hasFile('file')) { // 获取文件,file对应的是前端表单上传input的name $file = $request->file('file'); // Laravel5.3中多了一个写法 // $file = $request->file; // 初始化 $disk = QiniuStorage::disk('qiniu'); // 重命名文件 $fileName = md5($file->getClientOriginalName().time().rand()).'.'.$file->getClientOriginalExtension(); // 上传到七牛 $bool = $disk->put('iwanli/image_'.$fileName,file_get_contents($file->getRealPath())); // 判断是否上传成功 if ($bool) { $path = $disk->downloadUrl('iwanli/image_'.$fileName); return '上传成功,图片url:'.$path; } return '上传失败'; } return '没有文件'; }else{ return view('lx.image'); } } }
OK,刷新页面就能看到上传后的url地址了。这里只是演示一个最简单的实例,路由定义、视图样式、及逻辑层处理大家按照自己的项目的需求即可。
Buy me a cup of coffee :)
系统运维
2019-11-29 09:17:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
正确配置源站ECS的安全组和SLB的白名单,可以防止黑客直接攻击您的源站IP。本文介绍了源站服务器保护的相关配置方法。
背景信息
说明 源站保护不是必须的。没有配置源站保护不会影响正常业务转发,但可能导致攻击者在源站IP暴露的情况下,绕过Web应用防火墙直接攻击您的源站。
如何确认源站泄露?
您可以在非阿里云环境直接使用Telnet工具连接源站公网IP地址的业务端口,观察是否建立连接成功。如果可以连通,表示源站存在泄露风险,一旦黑客获取到源站公网IP就可以绕过WAF直接访问;如果无法连通,则表示当前不存在源站泄露风险。
例如,测试已接入WAF防护的源站IP 80端口和800端口是否能成功建立连接,测试结果显示端口可连通,说明存在源站泄露风险。
注意 配置安全组存在一定风险。在配置源站保护前,请注意以下事项: 请确保该ECS或SLB实例上的所有网站域名都已经接入Web应用防火墙。 当Web应用防火墙集群出现故障时,可能会将域名访问请求旁路回源至源站,确保网站正常访问。这种情况下,如果源站已配置安全组防护,则可能会导致源站无法从公网访问。 当Web应用防火墙集群扩容新的回源网段时,如果源站已配置安全组防护,可能会导致频繁出现5xx错误。
操作步骤 登录 云盾Web应用防火墙控制台 。 前往管理 > 网站配置页面,选择WAF实例所在的地区。 单击Web应用防火墙回源IP网段列表,查看Web应用防火墙所有回源IP段。
说明 WAF回源IP网段会定期更新,请关注定期变更通知。及时将更新后的回源IP网段添加至相应的安全组规则中,避免出现误拦截。
在WAF回源IP段对话框,单击复制IP段,复制所有回源IP。
参照以下步骤,配置源站只允许WAF回源IP进行访问。 源站是ECS 前往 ECS 实例列表 ,定位到需要配置安全组的ECS实例,单击其操作列下的管理。 切换到本实例安全组页面。 选择目标安全组,并单击其操作列下的配置规则。 单击添加安全组规则,并配置如下安全组规则:
说明 安全组规则授权对象支持输入“10.x.x.x/32”格式的IP网段,且支持添加多组授权对象(以“,”隔开),最多支持添加10组授权对象。 网卡类型:内网
说明 如果ECS实例的网络类型为经典网络,则网卡类型需设置为公网。 规则方向:入方向 授权策略:允许 协议类型:TCP 授权类型:地址段访问 端口范围:80/443 授权对象:粘贴步骤4中复制的所有Web应用防火墙回源IP段 优先级:1 为所有Web应用防火墙回源IP段添加安全组规则后,再添加如下安全组规则,拒绝公网入方向的所有IP段访问,优先级为100。 网卡类型:内网
说明 如果ECS实例的网络类型为经典网络,则网卡类型需设置为公网。 规则方向:入方向 授权策略:拒绝 协议类型:TCP 端口范围:80/443 授权类型:地址段访问 授权对象:0.0.0.0/0 优先级:100
说明 如果本安全组防护的服务器还与其他的IP或应用存在交互,需要将这些交互的IP和端口通过安全组一并加白放行,或者在最后添加一条优先级最小的全端口放行策略。 源站是SLB通过类似的方式,将Web应用防火墙的回源IP加入相应负载均衡实例的白名单,具体设置方法请参见 设置负载均衡白名单访问控制 。 登录 负载均衡管理控制台 ,前往访问控制页面,单击创建访问控制策略组。 填写策略组名称,添加WAF回源IP网段,单击确定。 在实例管理页面,选择相应的负载均衡实例。 在监听页签中,选择端口监听记录,单击更多 > 设置访问控制。 启用访问控制,选择访问控制方式为白名单,并选择所创建的WAF回源IP网段的访问控制策略组,单击确定。
后续步骤
源站保护配置完成后,您可以通过测试已接入WAF防护的源站IP80端口和8080端口是否能成功建立连接验证配置是否生效。如果显示端口无法直接连通,但网站业务仍可正常访问,则表示源站保护配置成功。
Buy me a cup of coffee :)
系统运维
2019-11-29 09:16:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
当一个https的请求到达IIS服务器时,https请求为加密状态,需要拿到相应的服务器证书解密请求。由于每个站点对应的证书不同,服务器需要通过请求中不同的主机头来判断需要用哪个证书解密,然而主机头作为请求的一部分也被加密。最终IIS只好使用第一个绑定到该IP:PORT的站点证书解密请求,从而有可能造成对于其他站点的请求失败而报错。
解决方法如下: 第一种解决方案将每个https站点绑定到不同的端口。但是这样的话客户端浏览网页时必须手动指定端口,例如 https://site.domain.com:444 第二种解决方案是为每个站点分配一个独立的ip,这样冲突就解决了,甚至主机头也不用添加了。 第三种解决方案是使用通配证书。我们采用通配证书颁发给 .domain.com,对于我们的示例中,应该采用颁发给 .marei.com的证书,这样任何访问该domain的请求均可以通过该证书解密,证书匹配错误也就不复存在了。 第四种解决方案是升级为IIS8,IIS8中添加的对于SNI(Server Name Indication)的支持,服务器可以通请求中提取出相应的主机头从而找到相应的证书。
方案分析:
方案1明显不太现实,我们不能让用户在访问我们的网站时还要指定端口号,一来不太好记,二来用户体验不好;
方案2虽然可行,但由于我们使用的是阿里云的服务器,是固定IP,没办法再给服务器再分配一个IP,故该方案不适合我们的场景;
方案3虽然可行,但我们使用的是域名型SSL证书,而且要购买通配型SSL证书的话,价格也比较贵,故该方案不适合我们的场景;
方案4,我们使用的服务器安装的操作系统是Windows Server 2012 R2,而该系统预装的就是IIS8,不是IIS8的可以自行升级为IIS8,在IIS8中,因为添加了对SNI的支持(具体概念及原理,读者可自行查阅相关资料,这里就不多说),所以可以很方便的解决我们所面临的问题。
现在就方案4做一下具体使用说明:
安装服务器证书,进入IIS,点击主机名,选择服务器证书,如下图:
点击右侧导入,如下图:
选择自己的证书文件,确定即可:
添加网站绑定,如下图
注意:类型选择https,端口号输入443,主机名填写自己的域名,“需要服务器名称只指示”前面的勾选框必须勾选,这个是解决问题的关键,SSL证书选择自己网站的证书(这里的选项是之前导入的证书);
6.确定后,该网站SSL证书绑定成功,可以使用https访问该网站,同样的方式,你需要配置另外一个网站(PS:除过主机名和SSL证书不一样外,其他配置都是一样的);
7.至此,两个网站都已配置成可以使用https访问;
8.测试是否成功:浏览器地址栏输入你要访问的地址:如https://www.domain.com,
如果浏览器中两个网站地址栏呈现类似以下状态,则配置成功:
如果一步一步操作到这里,那么恭喜你,你已经解决了这个问题。
Buy me a cup of coffee :)
系统运维
2019-11-29 09:16:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
【Apache下rewrite不成功】
不成功按照如下三步排查:
【第一步:打开rewrite 模块没有】
首先 我们找到apache安装目录下的 /conf/http.cnf
打开,文件 搜索rewrite 找到
#LoadModule rewrite_module modules/mod_rewrite.so
去掉前面的 # 改为
LoadModule rewrite_module modules/mod_rewrite.so
【第二步:打开文件允许重载没有】
继续在该文件中搜索 '.htaccess ' 我们找到 如注释对应的
AllowOverride None
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride None
然后我们将
AllowOverride None
改为
AllowOverride all
注意改动的位置 因为该文件 有多处 “AllowOverride None”
只有找到正确的位置才有效
【第三步:检查完前面两步】
重启 apache
【注意:如果windows下 无法保存文件 .htaccess】
①方案 使用 editplus打开文件 然后点击另存为副本
写上文件名 .htaccess 即可
②方案 找到http.conf 文件
在末尾加上:
AccessFileName .htaccess
重启 Apache
然后直接将文件名改为htaccess 即可
【最后】
如果仍然不起作用,请检查你的重写语法。
Buy me a cup of coffee :)
系统运维
2019-11-29 09:16:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
在CentOS下封停IP,有封杀网段和封杀单个IP两种形式。一般来说,现在的攻击者不会使用一个网段的IP来攻击(太招摇了),IP一般都是散列的。于是下面就详细说明一下封杀单个IP的命令,和解封单个IP的命令。
在CentOS下,使用ipteables来维护IP规则表。要封停或者是解封IP,其实就是在IP规则表中对入站部分的规则进行添加操作。
要封停一个IP,使用下面这条命令: iptables -I INPUT -s ***.***.***.*** -j DROP
要解封一个IP,使用下面这条命令: iptables -D INPUT -s ***.***.***.*** -j DROP
参数-I是表示Insert(添加),-D表示Delete(删除)。后面跟的是规则,INPUT表示入站,***.***.***.***表示要封停的IP,DROP表示放弃连接。
此外,还可以使用下面的命令来查看当前的IP规则表: iptables --list
比如现在要将123.44.55.66这个IP封杀,就输入: iptables -I INPUT -s 123.44.55.66 -j DROP
要解封则将-I换成-D即可,前提是 iptables 已经有这条记录。如果要想清空封掉的IP地址,可以输入: iptables --flush
要添加IP段到封停列表中,使用下面的命令: iptables -I INPUT -s 121.0.0.0/8 -j DROP
其实也就是将单个IP封停的IP部分换成了Linux的IP段表达式。关于IP段表达式网上有很多详细解说的,这里就不提了。
相信有了iptables的帮助,解决小的DDoS之类的攻击也不在话下!
附:其他常用的命令
编辑 iptables 文件 vi /etc/sysconfig/iptables
关闭/开启/重启防火墙 /etc/init.d/iptables stop #stop 关闭 #start 开启 #restart 重启
验证一下是否规则都已经生效: iptables -L
保存并重启iptables /etc/rc.d/init.d/iptables save service iptables restart
Buy me a cup of coffee :)
系统运维
2019-11-29 09:16:00