首页 文章 精选 留言 我的

精选列表

搜索[搭建],共10000篇文章
优秀的个人博客,低调大师

Android 仿IOS的PopupWindow和通用BasePopupWindow搭建

截图 pw.png 实现 1、BasePopupWindow.java 1.1、实现动态加载不同layout 1.2、动态配置是否弹出后背景半透明,关闭时候恢复(监听ondismiss,靠window类来变色) 1.3、一些基础性的方法抽象方法 1.4、为了更加复杂的样式和动效,可以继续扩展此类 /** * Created by wujn on 2018/10/29. * Version : v1.0 * Function: base popuwindow */ public abstract class BasePopupWindow extends PopupWindow implements View.OnClickListener{ /** * 上下文 */ private Context context; /** * 最上边的背景视图 */ private View vBgBasePicker; /** * 内容viewgroup */ private LinearLayout llBaseContentPicker; public BasePopupWindow(Context context) { super(context); this.context = context; View parentView = View.inflate(context, R.layout.base_popup_window_picker, null); vBgBasePicker = parentView.findViewById(R.id.v_bg_base_picker); llBaseContentPicker = (LinearLayout) parentView.findViewById(R.id.ll_base_content_picker); /*** * 添加布局到界面中 */ llBaseContentPicker.addView(View.inflate(context, bindLayout(), null)); setContentView(parentView); //设置PopupWindow弹出窗体的宽 this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); //设置PopupWindow弹出窗体的高 this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); //在PopupWindow里面就加上下面代码,让键盘弹出时,不会挡住pop窗口。 this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); setFocusable(true);//设置获取焦点 setTouchable(true);//设置可以触摸 setOutsideTouchable(true);//设置外边可以点击 ColorDrawable dw = new ColorDrawable(0xffffff); setBackgroundDrawable(dw); //设置SelectPicPopupWindow弹出窗体动画效果 this.setAnimationStyle(R.style.BottomDialogWindowAnim); initView(parentView); initListener(); initData(); vBgBasePicker.setOnClickListener(this); //是否需要屏幕半透明 setBackgroundHalfTransition(isNeedBackgroundHalfTransition()); } /** * 初始化布局 * * @return */ protected abstract int bindLayout(); /** * 初始化view * * @param parentView */ protected abstract void initView(View parentView); /** * 初始化数据 */ protected abstract void initData(); /** * 初始化监听 */ protected abstract void initListener(); /** * 为了适配7.0系统以上显示问题(显示在控件的底部) * * @param anchor */ @Override public void showAsDropDown(View anchor) { if (Build.VERSION.SDK_INT >= 24) { Rect rect = new Rect(); anchor.getGlobalVisibleRect(rect); int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom; setHeight(h); } super.showAsDropDown(anchor); if(isNeedBgHalfTrans){ backgroundAlpha(0.5f); } } /** * 展示在屏幕的底部 * * @param layoutid rootview */ public void showAtLocation(@LayoutRes int layoutid) { showAtLocation(LayoutInflater.from(context).inflate(layoutid, null), Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0); if(isNeedBgHalfTrans){ backgroundAlpha(0.5f); } } /** * 最上边视图的点击事件的监听 * * @param v */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.v_bg_base_picker: dismiss(); break; } } /** * 是否设置背景半透明 * */ public boolean isNeedBackgroundHalfTransition(){ return false; } private boolean isNeedBgHalfTrans = false; private void setBackgroundHalfTransition(boolean isNeed){ isNeedBgHalfTrans = isNeed; if(isNeedBgHalfTrans){ this.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { backgroundAlpha(1f); } }); } } /** * 设置添加屏幕的背景透明度 * @param bgAlpha */ private void backgroundAlpha(float bgAlpha) { WindowManager.LayoutParams lp = ((Activity)context).getWindow().getAttributes(); lp.alpha = bgAlpha; //0.0-1.0 ((Activity)context).getWindow().setAttributes(lp); } } 2、base_popup_window_picker.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <View android:id="@+id/v_bg_base_picker" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <LinearLayout android:id="@+id/ll_base_content_picker" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="vertical" /> </LinearLayout> 3、进入和退出时候的动画style <!--animanation--> <!-- 底部的dialog弹出的动画样式--> <style name="BottomDialogWindowAnim" parent="android:Animation"> <item name="android:windowEnterAnimation">@anim/popup_bottom_enter_anim</item> <item name="android:windowExitAnimation">@anim/popup_bottom_exit_anim</item> </style> 进入动画:popup_bottom_enter_anim.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="200" android:fromYDelta="100%p" android:toYDelta="0" /> <alpha android:duration="200" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set> 退出动画:popup_bottom_exit_anim.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="200" android:fromYDelta="0" android:toYDelta="50%p" /> <alpha android:duration="200" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set> 4、仿IOS的layout:popup_window_album_or_camera.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_shape_corner_white" android:orientation="vertical"> <Button android:id="@+id/btnCamera" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:text="拍照" android:textColor="@color/dodgerblue" android:textSize="@dimen/normal_text_size" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/gray_1" /> <Button android:id="@+id/btnAlbum" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:text="从相册中选择" android:textColor="@color/dodgerblue" android:textSize="@dimen/normal_text_size" /> </LinearLayout> <LinearLayout android:layout_marginTop="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_shape_corner_white" android:orientation="vertical"> <Button android:id="@+id/btnCancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:text="@string/cancel" android:textColor="@color/dodgerblue" android:textSize="@dimen/normal_text_size" /> </LinearLayout> </LinearLayout> item的背景style <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/white" /> <corners android:radius="6dp"/> <stroke android:width="1dp" android:color="@color/gray_1" /> </shape> 5、仿IOS的popuwindow类:AlbumOrCameraPopupWindow public class AlbumOrCameraPopupWindow extends BasePopupWindow { private Button btnCamera; private Button btnAlbum; private Button btnCancel; private OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener; public AlbumOrCameraPopupWindow(Context context,OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener) { super(context); this.onCameraOrAlbumSelectListener = onCameraOrAlbumSelectListener; } @Override public boolean isNeedBackgroundHalfTransition(){ return true; } @Override protected int bindLayout() { return R.layout.popup_window_album_or_camera; } @Override protected void initView(View parentView) { btnCamera = (Button) parentView.findViewById(R.id.btnCamera); btnAlbum = (Button) parentView.findViewById(R.id.btnAlbum); btnCancel = (Button) parentView.findViewById(R.id.btnCancel); } @Override protected void initData() { } @Override protected void initListener() { btnCamera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); if(onCameraOrAlbumSelectListener != null){ onCameraOrAlbumSelectListener.OnSelectCamera(); } } }); btnAlbum.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); if(onCameraOrAlbumSelectListener != null){ onCameraOrAlbumSelectListener.OnSelectAlbum(); } } }); btnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); } } 选择相机或者相册的监听接口 public interface OnCameraOrAlbumSelectListener { public void OnSelectCamera(); public void OnSelectAlbum(); } 6、具体使用 private AlbumOrCameraPopupWindow ACWindow; private void initListener(){ ACWindow = new AlbumOrCameraPopupWindow(this, onCameraOrAlbumSelectListener); btnIosPopupWindow.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(ACWindow != null && !ACWindow.isShowing()){ ACWindow.showAtLocation(R.layout.activity_view_popup_window); } } }); } /**选择相机或者相册*/ private OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener = new OnCameraOrAlbumSelectListener() { @Override public void OnSelectCamera() { LogUtil.i("OnSelectCamera..."); ToastUtil.showShort(instance, "相机"); } @Override public void OnSelectAlbum() { LogUtil.i("OnSelectAlbum..."); ToastUtil.showShort(instance, "从相册中选择"); } }; 朝CV工程师又进一步~~~

优秀的个人博客,低调大师

使用docker在CentOS7上搭建WordPress

自己课题组的网页挂了,老板一句话让我们自己写一个。结果被我拖了半年,结果丢给师弟,师弟决定用WordPress, 于是我就去给他配置服务器环境。 首先你得知道什么叫做WordPress, 它是一个基于PHP和MySQL的开源的博客管理工具,用于管理你的写作内容。由于它十分容易部署,而且有很多好看的主题可以供你选择,因此被许多人使用。 一般的安装方法是,你得有一个服务器,然后在服务器上按照PHP,MySQL, Apache/NGINX, 之后下载WordPress的安装包,进行编译安装。 只从有了docker,环境配置部分就得到了简化,并且你不用担心在准备环境的时候,要去调整原来的PHP版本,去修改MySQL的版本,还要专门折腾Apache或者NGINX。 后续的步骤都要求你对服务器有绝对的控制权,也就是说后续没有特别说明,我们都是以root用户运行命令 安装Docker Docker是目前服务器部署届的佼佼者,无论是部署网页,还是部署你的生信分析平台,只要你写好dockfile(一种描述部署规则的文件), 在任意的服务器上,安装好Docker,就可以构建出一个完全一样的运行环境。 我用的的是CentOS7, 版本信息如下 uname -r 3.10.0-862.el7.x86_64 然后用YUM工具进行安装, yum update -y yum install docker -y 由于国情,我们需要对配置一下docker的下载镜像,提高一下后续的加载速度。 使用vim编辑 /etc/docker/daemon.json, 增加如下内容。 { "registry-mirrors": ["https://6xacs6l2.mirror.aliyuncs.com"] } 启动我们的docker服务 systemctl start docker.service 默认情况下,只有root用户和docker组的用户才能访问Docker引擎的Unix socket。当然直接用root权限使用docker太过危险,建议新建一个docker用户,然后加入docker用户组 groupadd docker useradd -g docker docker 后续的操作用su docker切换到docker用户进行。 安装WordPress 首先让我们拉取WordPress的镜像 docker pull wordpress:latest WordPress的详细使用方法见https://hub.docker.com/_/wordpress/, 运行命令是 docker run --name some-wordpress --link some-mysql:mysql -d wordpress 先做一波参数说明: --name 容器的的名字 --link 和其他容器做连接 ·-d/--detach` 后台运行 但是直接这样运行是绝对会报错的,你需要再拉取一个MySQL容器, docker pull mysql:5.6 从MySQL镜像中运行单独的容器 docker run -d --privileged=true --name myMysql -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -p 33306:3306 mysql:5.6 再来一波参数解释: -p: 端口映射,33306表示宿主,3306表示容器中的端口。 这里表示将宿主机的33306映射给镜像的3306. -e: 环境变量, 环境变量和具体的Docker容器制作时设置有关,这里表示设置镜像中MySQL的root 密码时123456 -v: 指定数据卷,也就是将我们MySQL容器的/var/lib/mysql映射到宿主机的/data/mysql --privileged=true: CentOS系统下的安全Selinux禁止了一些安全权限,导致MySQL容器在运行时会因为权限不足而报错,所以需要增加该选项 用docker ps -a 查看MySQL是否正常运行,出现错误的话,需要用docker stop 容器名停止运行,然后用docker rm 容器名删除容器,之后去掉-d选项重新运行排查错误。 当我们配置好MySQL后,下一步才是运行WordPress docker run -d --name mwp -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_PASSWORD=123456 -p 1080:80 --link myMysql:mysql wordpress 这里我们设置了两个环境变量,"WORDPRESS_DB_HOST"和"WORDPRESS_DB_PASSWORD", 但比较重要的有下面几个 "WORDPRESS_DB_HOST": 链接的docker的MySQL的IP地址和端口,一般设置成mysql表示用默认的设置 "WORDPRESS_DB_USER": 以什么用户使用MySQL,默认是root "WORDPRESS_DB_PASSWORD" 这设置MySQL的登陆用户密码,由于上一项是默认的root,所以这一项和之前的"MYSQL_ROOT_PASSWORD“要相同。 "WORDPRESS_DB_NAME": 数据库的表名,不需要修改,用默认的”wordpress"就行 之后在浏览器上用你服务器的IP,和映射出的端口号(我的是1080),就会得到配置界面 注意:尽管将容器的80端口映射给主机的1080,不需要用到root权限,但CentOS默认的防火墙禁止了大于1000后的所有端口,所以我们要开启这个端口 firewall-cmd --zone=public --add-port=8000/tcp --permanent firewall-cmd --reload #重载 后面就是你自己挑选主题的时刻了。 参考资料: https://www.cnblogs.com/qingyunzong/p/9011006.html https://blog.csdn.net/xiaoping0915/article/details/79515309 https://hub.docker.com/_/wordpress/

优秀的个人博客,低调大师

阿里云基于容器的微服务平台搭建

基于阿里云构建高可用持续集成微服务平台 1. 平台需求: 1.1 应用情况: 使用 HSF 或者 Dubbo 提供微服务 使用 Spring-cloud 提供 httprestful 微服务 有自定义协议的 RPC 服务 数十个应用; 业务逻辑经常串起一批微服务 1.2 要求: 安全性要求高 高可用 高性能 敏捷开发,持续集成 1.3 基础架构 开发环境包含日常开发环境,预发环境,线上生产环境 2. 基础设施: 2.1 虚拟服务器 2.2 虚拟网络服务 2.3 日志服务 2.4 云监控 3. Kubernetes 容器服务集群 3.1 容器镜像服务 3.2 打包应用上容器镜像服务 3.3 分批发布应用 3.4 监控 k8s 容器应用 3.5 k8s 集群日志服务 4. 中间件 4.1 MetaQ 消息队列 4.2 Drds 分库分表中间件 4.3 EDAS 企业级组件 5. 高可

优秀的个人博客,低调大师

大数据实时查询-Presto集群部署搭建

Presto介绍 Presto是一个分布式SQL查询引擎, 它被设计为用来专门进行高速、实时的数据分析。它支持标准的ANSI SQL,包括复杂查询、聚合(aggregation)、连接(join)和窗口函数(window functions)。Presto的运行模型和Hive或MapReduce有着本质的区别。Hive将查询翻译成多阶段的MapReduce任务, 一个接着一个地运行。 每一个任务从磁盘上读取输入数据并且将中间结果输出到磁盘上。 然而Presto引擎没有使用MapReduce。它使用了一个定制的查询和执行引擎和响应的操作符来支持SQL的语法。除了改进的调度算法之外, 所有的数据处理都是在内存中进行的。 不同的处理端通过网络组成处理的流水线。 这样会避免不必要的磁盘读写和额外的延迟。 这种流水线式的执行模型会在同一时间运行多个数据处理段, 一旦数据可用的时候就会将数据从一个处理段传入到下一个处理段。 这样的方式会大大的减少各种查询的端到端响应时间。 Presto查询引擎是一个Master-Slave的架构,由一个Coordinator节点,一个Discovery Server节点,多个Worker节点组成,Discovery Server通常内嵌于Coordinator节点中。Coordinator负责解析SQL语句,生成执行计划,分发执行任务给Worker节点执行。Worker节点负责实际执行查询任务。Worker节点启动后向Discovery Server服务注册,Coordinator从Discovery Server获得可以正常工作的Worker节点。如果配置了Hive Connector,需要配置一个Hive MetaStore服务为Presto提供Hive元信息,Worker节点与HDFS交互读取数据。 image.png Presto支持从以下版本的Hadoop中读取Hive数据:支持以下文件类型:Text, SequenceFile, RCFile, ORC Apache Hadoop 1.x (hive-hadoop1) Apache Hadoop 2.x (hive-hadoop2) Cloudera CDH 4 (hive-cdh4) Cloudera CDH 5 (hive-cdh5) 此外,需要有远程的Hive元数据。 不支持本地或嵌入模式。 Presto不使用MapReduce,只需要HDFS. 部署安装 https://prestodb.io/docs/current/installation/deployment.html 下载 https://repo1.maven.org/maven2/com/facebook/presto/presto-server/ 将安装包copy至服务器 创建log目录 sudo mkdir /opt/bigdata sudo mkdir /opt/bigdata/presto sudo mkdir /opt/bigdata/presto/data 解压安装包 目录/opt/bigdata/presto/ sudo tar -zxvf /opt/bigdata/presto/presto-server-0.208.tar.gz sudo mkdir /opt/bigdata/presto/presto-server-0.208/catalog sudo mkdir /opt/bigdata/presto/presto-server-0.208/etc 更改用户组 sudo chgrp -R ec2-user /opt/bigdata sudo chown -R ec2-user /opt/bigdata 配置文件 在presto目录下创建etc目录,并在etc目录下,创建以下配置文件 config.properties :Presto 服务配置 node.properties :环境变量配置,每个节点特定配置 jvm.config :Java虚拟机的命令行选项 log.properties: 允许你根据不同的日志结构设置不同的日志级别 catalog目录 :每个连接者配置(data sources) coordinator config.properties 包含了Presto server的所有配置信息。 每个Presto server既是一个coordinator也是一个worker。 但是在大型集群中,处于性能考虑,建议单独用一台机器作为 coordinator,一个coordinator的etc/config.properties应该至少包含以下信息: coordinator=true node-scheduler.include-coordinator=false http-server.http.port=9000 query.max-memory=30GB query.max-total-memory-per-node=6GB query.max-memory-per-node=2GB discovery-server.enabled=true discovery.uri=http://10.111.0.0:9000 参数说明: coordinator:指定是否运维Presto实例作为一个coordinator(接收来自客户端的查询情切管理每个查询的执行过程) node-scheduler.include-coordinator:是否允许在coordinator服务中进行调度工作, 对于大型的集群,在一个节点上的Presto server即作为coordinator又作为worke将会降低查询性能。因为如果一个服务器作为worker使用,那么大部分的资源都会被worker占用,那么就不会有足够的资源进行关键任务调度、管理和监控查询执行 http-server.http.port:指定HTTP server的端口。Presto 使用 HTTP进行内部和外部的所有通讯 task.max-memory=1GB:一个单独的任务使用的最大内存 (一个查询计划的某个执行部分会在一个特定的节点上执行)。 这个配置参数限制的GROUP BY语句中的Group的数目、JOIN关联中的右关联表的大小、ORDER BY语句中的行数和一个窗口函数中处理的行数。 该参数应该根据并发查询的数量和查询的复杂度进行调整。如果该参数设置的太低,很多查询将不能执行;但是如果设置的太高将会导致JVM把内存耗光 discovery-server.enabled:Presto 通过Discovery 服务来找到集群中所有的节点。为了能够找到集群中所有的节点,每一个Presto实例都会在启动的时候将自己注册到discovery服务。Presto为了简化部署,并且也不想再增加一个新的服务进程,Presto coordinator 可以运行一个内嵌在coordinator 里面的Discovery 服务。这个内嵌的Discovery 服务和Presto共享HTTP server并且使用同样的端口 discovery.uri:Discovery server的URI。由于启用了Presto coordinator内嵌的Discovery 服务,因此这个uri就是Presto coordinator的uri。注意:这个URI一定不能以“/“结尾 worker config.properties coordinator=false http-server.http.port=9000 query.max-memory=30GB query.max-total-memory-per-node=10GB query.max-memory-per-node=2GB discovery.uri=http://10.111.0.0:9000 node.properties 包含针对于每个节点的特定的配置信息。 一个节点就是在一台机器上安装的Presto实例,etc/node.properties配置文件至少包含如下配置信息 node.environment=presto node.id= node.data-dir=/opt/bigdata/presto/data 参数说明: node.environment: 集群名称, 所有在同一个集群中的Presto节点必须拥有相同的集群名称 node.id: 每个Presto节点的唯一标示。每个节点的node.id都必须是唯一的。在Presto进行重启或者升级过程中每个节点的node.id必须保持不变。如果在一个节点上安装多个Presto实例(例如:在同一台机器上安装多个Presto节点),那么每个Presto节点必须拥有唯一的node.id node.data-dir: 数据存储目录的位置(操作系统上的路径), Presto将会把日期和数据存储在这个目录下 jvm.config 包含一系列在启动JVM的时候需要使用的命令行选项。这份配置文件的格式是:一系列的选项,每行配置一个单独的选项。由于这些选项不在shell命令中使用。 因此即使将每个选项通过空格或者其他的分隔符分开,java程序也不会将这些选项分开,而是作为一个命令行选项处理,信息如下: -server -Xmx10G -Xms10G -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent -XX:+CMSClassUnloadingEnabled -XX:+AggressiveOpts -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError=kill -9 %p -XX:ReservedCodeCacheSize=150M -XX:CMSInitiatingOccupancyFraction=70 log.properties 这个配置文件中允许你根据不同的日志结构设置不同的日志级别。每个logger都有一个名字(通常是使用logger的类的全标示类名). Loggers通过名字中的“.“来表示层级和集成关系,信息如下: com.facebook.presto=DEBUG 配置日志等级,类似于log4j。四个等级:DEBUG,INFO,WARN,ERROR Catalog Properties 通过在etc/catalog目录下创建catalog属性文件来完成catalogs的注册。 例如:可以先创建一个etc/catalog/jmx.properties文件,文件中的内容如下,完成在jmxcatalog上挂载一个jmxconnector connector.name=jmx 在etc/catalog目录下创建hive.properties,信息如下: connector.name=hive-hadoop2 hive.metastore.uri=thrift://10.111.0.0:9083 hive.config.resources=/opt/bigdata/hadoop/hadoop-2.8.0/etc/hadoop/core-site.xml, /opt/bigdata/hadoop/hadoop-2.8.0/etc/hadoop/hdfs-site.xml hive.allow-drop-table=true 启动 在安装目录的bin/launcher文件,就是启动脚本。Presto可以使用如下命令作为一个后台进程启动: bin/launcher start 也可以在前台运行, 可查看具体的日志 bin/launcher run 停止服务进程命令 bin/launcher stop 查看进程: ps -aux|grep PrestoServer 或 jps 安装cli https://repo1.maven.org/maven2/com/facebook/presto/presto-cli/ ./presto-cli-0.208-executable.jar --server 10.111.0.86:9000 --catalog hive --schema db_name; WebUI http://ip:9000/ui/ image.png 欢迎关注 高广超的简书博客 与 收藏文章 !欢迎关注 头条号:互联网技术栈 ! 个人介绍: 高广超:多年一线互联网研发与架构设计经验,擅长设计与落地高可用、高性能、可扩展的互联网架构。目前从事大数据相关研发与架构工作。 本文首发在 高广超的简书博客 转载请注明!

优秀的个人博客,低调大师

搭建私有git服务器进行版本控制

一、安装git 分别在服务器和本地安装最新版本的git 1、服务器上源码安装最新版git 通常centos上使用yum源安装的git版本过低 检查系统上是否已经安装git,若已有则卸载 // 查看当前git版本# git --version git version1.7.1// 卸载旧版本# yum remove -y git 安装依赖包,下载最新版本git源码 #yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel#wget https://github.com/git/git/archive/v2.13.2.tar.gz#tar zxf v2.13.2.tar.gz 安装git,配置环境变量 #cdgit-2.13.2#make prefix=/usr/local/git all#make prefix=/usr/local/git install#echo"export PATH=$PATH:/usr/local/git/bin">> /etc/bashrc#source/etc/bashrc // 实时生效 查看git版本号,正确显示则安装成功 # git --version gitversion2.13.2 若编译时报错如下 libgit.a(utf8.o): Infunction`reencode_string_iconv': /usr/local/src/git-2.13.2/utf8.c:463: undefined reference to `libiconv' libgit.a(utf8.o): Infunction`reencode_string_len': /usr/local/src/git-2.13.2/utf8.c:524: undefined reference to `libiconv_open' /usr/local/src/git-2.13.2/utf8.c:535: undefined reference to `libiconv_close' /usr/local/src/git-2.13.2/utf8.c:529: undefined reference to `libiconv_open' collect2: ld returned 1exitstatus make: *** [git-credential-store] Error 1 可以按照如下方式解决 // 对之前git的make 操作进行 make clean#make clean#wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz#tar zxf libiconv-1.14.tar.gz#cdlibiconv-1.14#./configure --prefix=/usr/local/libiconv#make && make install // 创建一个软链接到/usr/lib#ln -s /usr/local/lib/libiconv.so /usr/lib#ln -s /usr/local/lib/libiconv.so.2 /usr/lib 然后 #make configure#./configure --prefix=/usr/local/git --with-iconv=/usr/local/libiconv/#make && make install#echo"export PATH=$PATH:/usr/local/git/bin">> /etc/bashrc#source/etc/bashrc 配置git 用户名及邮箱 #git config --global user.name'your name'#git config --global user.email'your email address' 2、本地安装最新版git(此处演示为Windows上安装) windows上安装直接下载最新版安装包,双击->下一步… 即可完成安装 所有选项默认即可 打开 git-bash,配置git 用户名和邮箱,同服务端配置第6步 想要学习Java高架构、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战学习架构师视频免费获取 架构群:835544715 点击链接加入群聊【JAVA高级架构】:https://jq.qq.com/?_wv=1027&k=5dbERkY 二、服务器设置 1、添加一个git用户,为安全起见禁用shell登录 # useradd git // 为安全起见,禁用 git 用户的shell登录 #vim/etc/passwd // 修改 git 用户的shell为 git-shell,路径使用 which git-shell查看 // 找到如下一行 git:x:1001:1001::/home/git:/bin/bash // 修改成如下 git:x:1001:1001::/home/git:/usr/local/git/bin/git-shell 2、初始化一个项目目录为一个仓库 // 进入到项目目录# git init 3、将该目录克隆成为裸仓库(作为中介)并设置裸仓库所有者为git用户 // 创建一个裸仓库#gitclone--bare ProjectPath /srv/myProject.git 4、将裸仓库添加为远程仓库 // 进入到项目目录# git remote add origin /srv/myProject.git// 修改远程仓库所属主和所属组# chown -R git.git /srv/myProject.git 5、将服务器上的项目添加到远程仓库即 /srv/myProject.git #git add .#git commit -m'comment'#git push origin master 6、在该用户的家目录下面保存本地用户的公钥 #su git$cd~$make .ssh$chmod 700 .ssh$cd.ssh$touch authorized_keys$chmod 600 authorized_keys // 然后在 authorized_keys 文件中加入本地用户的公钥 id_rsa.pub 7、打开git服务器的RSA认证 # vim /etc/ssh/sshd_config//找到下面3行并去掉注释1.RSAAuthenticationyes 2.PubkeyAuthenticationyes 3.AuthorizedKeysFile .ssh/authorized_keys 三、本地设置(Windows端) 1、生成公钥并交给服务端 // 打开 git-bash,生成公钥 $ ssh-keygen-t rsa// 在用户目录下的.ssh目录里面会生成 id_rsa, id_rsa.pub// 将 id_rsa.pub 里的内容拷贝到服务器上 2、在保存公钥的同级目录下面新建config文件指定ssh端口(可选) ==类似使用搬瓦工VPS的可能默认ssh端口不是22的需要配置这个== Host your domain nameorserver ip User 服务端添加的git用户名 Hostname your domain nameorserver ip Port ssh 端口 IdentityFile ~/.ssh/id_rsa 3、从服务器克隆项目到本地 $gitcloneyrscgit@yrsc0597.com:/srv/yrsc.git 4、添加远程仓库 四、测试 本地更改,添加,删除项目,然后推送修改到远程仓库 服务器项目目录下拉取最新的版本

优秀的个人博客,低调大师

redis 一主二从三哨兵的搭建

环境准备 三台独立的linux主机 内网IP分别为:172.31.175.142、172.31.175.143、172.31.175.144 分别创建带主目录的普通用户,比如useradd wx -m 安装redis 分别在各个主机上安装redis,以172.31.175.142为例,步骤如下 #下载4.0稳定版 wget http://download.redis.io/releases/redis-4.0.11.tar.gz #解压到用户主目录 tar -xzvf redis-4.0.11.tar.gz -C /home/wx #进入用户主目录 cd /home/wx #重命名解压的文件 mv redis-4.0.11 redis #进入redis目录 cd redis #编译 make #安装,PREFIX指定安装路径 make PREFIX=/home/wx/redis install 主从/哨兵配置 一主(master)二从(slave)三哨兵(sentinel)的配置目标, 如下 redis.conf配置主从, sentinel.conf配置哨兵 conf里面很多初始的配置项可以不做修改, 对于需要修改或新增的配置项, 说明如下 通用配置 下面3项,务必在每个redis.conf里进行修改,在每个sentinel.conf里新增(默认没有) #支持内网/本地访问,比如 bind 172.31.175.142 127.0.0.1 bind 本机内网IP 127.0.0.1 #支持后台运行,默认值为no daemonize yes #日志文件,比如redis.log、sentinel.log logfile xxx.log slave的配置 在2个slave的redis.conf下指定master #指定master slaveof 172.31.175.142 6379 sentinel的配置 在3个sentinel.conf下指定监控的master #指定监控的master,最后一位表示quorum(法人数量),即认定master'客观下线'成立的最低票数 sentinel monitor mymaster 172.31.175.142 6379 2 主从/哨兵运行 分别启动主从redis, 验证没问题,再分别启动哨兵,假设已进入redis/bin目录 运行redis 1,启动redis ./redis-server ../redis.conf 2, 查看日志 tail -100f ../redis.log 3, 连接redis ./redis-cli 4,查看主从信息 cli连接redis成功后, 输入info replication 下面是master的replication信息 下面是其中一个slave的replication信息 5, 测试主从同步 在master上写入变量, 在slave上查看是否同步, 此过程略. 运行哨兵 ./redis-sentinel ../sentinel.conf 一个哨兵的日志如下, 可以看出哨兵正在监听,并已识别到2个slave 故障转移 模拟发生故障,进入master主机172.31.175.142, kill掉redis-server进程. 接下来, 查看各个哨兵的日志, 大抵可以看出哨兵的工作过程, 如下 1, 主观下线(sdown) 当某个哨兵心跳检测master超时后,则认定其sdown +sdown master mymaster 172.31.175.142 6379 2, 客观下线(odown) 当认定sdown的哨兵数>=quorum时,则master下线事实最终成立,即odown +odown master mymaster 172.31.175.142 6379 #quorum 2/2 3, 选举哨兵leader 各哨兵协商,选举出一个leader,由其进行故障转移操作 +vote-for-leader 1dd7873228b4bf30c1668d55a28b3036072ee9de 1 4, 故障转移 选择一个slave作为新的master, 并将其他节点设置为新master的slave(刚才已下线的老master的配置文件也会被设置slaveof...) +switch-master mymaster 172.31.175.142 6379 172.31.175.144 6379 当故障转移成功后, redis就是一主一从,如下 主机 角色 172.31.175.142 哨兵、master 172.31.175.143 哨兵、slave 172.31.175.144 哨兵、slave->master 进入新的master172.31.175.144,查看redis的主从信息, 还剩一从172.31.175.143 故障恢复 模拟故障恢复,进入老的master172.31.175.142, 重启刚才kill掉的redis,之后查看其主从信息, 发现老的master已经变成slave了,如下 //因为172.31.175.142的redis.conf在故障转移时被修改了,所以重启之后就直接成了slave 进入新的master 172.31.175.144下,再去查看最新的主从信息, 发现加入了新的slave,如下 故障恢复之后, redis恢复到了一主二从三哨兵, 只不过master/slave换了地方, 如下 //若此时想要调整master/slave, 则需要手工操作, 所以为了方便起见,建议在故障转移之前备份配置文件.

优秀的个人博客,低调大师

史上最详细、最全面的Hadoop环境搭建

前言 这是一篇入门文章,Hadoop的学习方法很多,网上也有很多学习路线图。本文的思路是:以安装部署Apache Hadoop2.x版本为主线,来介绍Hadoop2.x的架构组成、各模块协同工作原理、技术细节。安装不是目的,通过安装认识Hadoop才是目的。 第一部分:Linux环境安装 第一部分介绍Linux环境的安装、配置、Java JDK安装等。 第二部分:Hadoop本地模式安装 Hadoop本地模式只是用于本地开发调试,或者快速安装体验Hadoop,这部分做简单的介绍。 第三部分:Hadoop伪分布式模式安装 伪分布式的意思是虽然各个模块是在各个进程上分开运行的,但是只是运行在一个操作系统上的,并不是真正的分布式。 第四部分:完全分布式安装 完全分布式模式才是生产环境采用的模式,Hadoop运行在服务器集群上,生产环境一般都会做HA,以实现高可用。 第一部分:Linux环境安装 第一步、配置Vmware NAT网络 这里选择NAT模式,各个虚拟机通过NAT使用宿主机的IP来访问外网。第二步、安装Linux操作系统 操作系统的安装步骤请自行参考公众号前期文章,然后将各机器hosts文件统一。关闭防火墙:学习环境可以直接把防火墙关闭掉。用root用户登录后,执行查看防火墙状态。关闭selinux:selinux是Linux一个子安全机制,学习环境可以将它禁用。 第三步、安装JDK 查看是否已经安装了java JDK。 [root@bigdata-senior01Desktop]#java–version 注意:Hadoop机器上的JDK,最好是Oracle的JavaJDK,不然会有一些问题,比如可能没有JPS命令。 如果安装了其他版本的JDK,卸载掉。 将jdk-7u67-linux-x64.tar.gz解压到/opt/modules目录下 [root@bigdata-senior01/]#tar-zxvfjdk-7u67-linux-x64.tar.gz-C/opt/modules #添加环境变量 设置JDK的环境变量JAVA_HOME。需要修改配置文件/etc/profile,追加 exportJAVA_HOME="/opt/modules/jdk1.7.0_67" exportPATH=$JAVA_HOME/bin:$PATH #修改完毕后,执行source/etc/profile #安装后再次执行java–version,可以看见已经安装完成。 [root@bigdata-senior01/]#java-version javaversion"1.7.0_67" Java(TM)SERuntimeEnvironment(build1.7.0_67-b01) JavaHotSpot(TM)64-BitServerVM(build24.65-b04,mixedmode) 第二部分:Hadoop本地模式安装 Hadoop部署模式有:本地模式、伪分布模式、完全分布式模式、HA完全分布式模式。区分的依据是NameNode、DataNode、ResourceManager、NodeManager等模块运行在几个JVM进程、几个机器。 模式名称 各个模块占用的JVM进程数 各个模块运行在几个机器数上 本地模式 1个 1个 伪分布式模式 N个 1个 完全分布式模式 N个 N个 HA完全分布式 N个 N个 本地模式部署 本地模式是最简单的模式,所有模块都运行与一个JVM进程中,使用的本地文件系统,而不是HDFS,本地模式主要是用于本地开发过程中的运行调试用。默认的就是本地模式。创建一个存放本地模式hadoop的目录。 [hadoop@bigdata-senior01modules]$mkdir/opt/modules/hadoopstandalone #解压hadoop文件 [hadoop@bigdata-senior01modules]$tar-zxf/opt/sofeware/hadoop-2.5.0.tar.gz-C/opt/modules/hadoopstandalone/ #确保JAVA_HOME环境变量已经配置好 [hadoop@bigdata-senior01modules]$echo${JAVA_HOME} /opt/modules/jdk1.7.0_67 运行MapReduce程序,验证,我们这里用hadoop自带的wordcount例子来在本地模式下测试跑mapreduce。 #准备mapreduce输入文件wc.input [hadoop@bigdata-senior01modules]$cat/opt/data/wc.input hadoopmapreducehive hbasesparkstorm sqoophadoophive sparkhadoop #运行hadoop自带的mapreduceDemo [hadoop@bigdata-senior01hadoopstandalone]$bin/hadoopjarshare/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jarwordcount/opt/data/wc.inputoutput2 #这里可以看到jobID中有local字样,说明是运行在本地模式下的。 #查看输出文件,本地模式下,mapreduce的输出是输出到本地。 [hadoop@bigdata-senior01hadoopstandalone]$lloutput2 total4 -rw-r--r--1hadoophadoop60Jul712:50part-r-00000 -rw-r--r--1hadoophadoop0Jul712:50_SUCCESS #输出目录中有_SUCCESS文件说明JOB运行成功,part-r-00000是输出结果文件。 第三部分:Hadoop伪分布式模式安装 伪分布式Hadoop部署过程 Hadoop所用的用户设置 #创建一个名字为hadoop的普通用户 [root@bigdata-senior01~]#useraddhadoop [root@bigdata-senior01~]#passwdhadoop #给hadoop用户sudo权限 [root@bigdata-senior01~]#vim/etc/sudoers #设置权限,学习环境可以将hadoop用户的权限设置的大一些,但是生产环境一定要注意普通用户的权限限制。 rootALL=(ALL)ALL hadoopALL=(root)NOPASSWD:ALL #注意:如果root用户无权修改sudoers文件,先手动为root用户添加写权限。 [root@bigdata-senior01~]#chmodu+w/etc/sudoers #切换到hadoop用户 [root@bigdata-senior01~]#su-hadoop [hadoop@bigdata-senior01~]$ 创建存放hadoop文件的目录 [hadoop@bigdata-senior01~]$sudomkdir/opt/modules #将hadoop文件夹的所有者指定为hadoop用户,如果存放hadoop的目录的所有者不是hadoop,之后hadoop运行中可能会有权限问题,那么就讲所有者改为hadoop。 [hadoop@bigdata-senior01~]#sudochown-Rhadoop:hadoop/opt/modules 解压Hadoop目录文件 #复制hadoop-2.5.0.tar.gz到/opt/modules目录下。解压hadoop-2.5.0.tar.gz。 [hadoop@bigdata-senior01~]#cd/opt/modules [hadoop@bigdata-senior01hadoop]#tar-zxvfhadoop-2.5.0.tar.gz 配置Hadoop #配置Hadoop环境变量 [hadoop@bigdata-senior01hadoop]#vim/etc/profile #追加配置: exportHADOOP_HOME="/opt/modules/hadoop-2.5.0" exportPATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH #执行:source/etc/profile使得配置生效 #验证HADOOP_HOME参数: [hadoop@bigdata-senior01/]$echo$HADOOP_HOME /opt/modules/hadoop-2.5.0 #配置hadoop-env.sh、mapred-env.sh、yarn-env.sh文件的JAVA_HOME参数 [hadoop@bigdata-senior01~]$sudovim${HADOOP_HOME}/etc/hadoop/hadoop-env.sh #修改JAVA_HOME参数为: exportJAVA_HOME="/opt/modules/jdk1.7.0_67" 配置core-site.xml [hadoop@bigdata-senior01~]{HADOOP_HOME}/etc/hadoop/core-site.xml #(1)fs.defaultFS参数配置的是HDFS的地址。 <property> <name>fs.defaultFS</name> <value>hdfs://bigdata-senior01.chybinmy.com:8020</value> </property> #(2)hadoop.tmp.dir配置的是Hadoop临时目录,比如HDFS的NameNode数据默认都存放这个目录下,查看*-default.xml等默认配置文件,就可以看到很多依赖${hadoop.tmp.dir}的配置。默认的hadoop.tmp.dir是/tmp/hadoop-${user.name},此时有个问题就是NameNode会将HDFS的元数据存储在这个/tmp目录下,如果操作系统重启了,系统会清空/tmp目录下的东西,导致NameNode元数据丢失,是个非常严重的问题,所有我们应该修改这个路径。 #创建临时目录: [hadoop@bigdata-senior01hadoop-2.5.0]$sudomkdir-p/opt/data/tmp #将临时目录的所有者修改为hadoop [hadoop@bigdata-senior01hadoop-2.5.0]$sudochown–Rhadoop:hadoop/opt/data/tm #修改hadoop.tmp.dir <property> <name>hadoop.tmp.dir</name> <value>/opt/data/tmp</value> </property> 配置、格式化、启动HDFS #配置hdfs-site.xml [hadoop@bigdata-senior01hadoop-2.5.0]$vim${HADOOP_HOME}/etc/hadoop/hdfs-site.xm <property> <name>dfs.replication</name> <value>1</value> </property> #dfs.replication配置的是HDFS存储时的备份数量,因为这里是伪分布式环境只有一个节点,所以这里设置为1。格式化HDFS。 [hadoop@bigdata-senior01~]$hdfsnamenode–format #格式化是对HDFS这个分布式文件系统中的DataNode进行分块,统计所有分块后的初始元数据的存储在NameNode中。格式化后,查看core-site.xml里hadoop.tmp.dir(本例是/opt/data目录)指定的目录下是否有了dfs目录,如果有,说明格式化成功。注意:格式化时,这里注意hadoop.tmp.dir目录的权限问题,应该hadoop普通用户有读写权限才行,可以将/opt/data的所有者改为hadoop。 [hadoop@bigdata-senior01hadoop-2.5.0]$sudochown-Rhadoop:hadoop/opt/data #查看NameNode格式化后的目录。 [hadoop@bigdata-senior01~]$ll/opt/data/tmp/dfs/name/current fsimage是NameNode元数据在内存满了后,持久化保存到的文件。 fsimage*.md5是校验文件,用于校验fsimage的完整性。 seen_txid是hadoop的版本 vession文件里保存: namespaceID:NameNode的唯一ID。 clusterID:集群ID,NameNode和DataNode的集群ID应该一致,表明是一个集群。 #MonJul0417:25:50CST2016 namespaceID=2101579007 clusterID=CID-205277e6-493b-4601-8e33-c09d1d23ece4 cTime=0 storageType=NAME_NODE blockpoolID=BP-1641019026-127.0.0.1-1467624350057 layoutVersion=-57 启动NameNode [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/sbin/hadoop-daemon.shstartnamenode startingnamenode,loggingto/opt/modules/hadoop-2.5.0/logs/hadoop-hadoop-namenode-bigdata-senior01.chybinmy.com.out 启动DataNode [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/sbin/hadoop-daemon.shstartdatanode startingdatanode,loggingto/opt/modules/hadoop-2.5.0/logs/hadoop-hadoop-datanode-bigdata-senior01.chybinmy.com.out 启动SecondaryNameNode [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/sbin/hadoop-daemon.shstartsecondarynamenode startingsecondarynamenode,loggingto/opt/modules/hadoop-2.5.0/logs/hadoop-hadoop-secondarynamenode-bigdata-senior01.chybinmy.com.out JPS命令查看是否已经启动成功,有结果就是启动成功了。 [hadoop@bigdata-senior01hadoop-2.5.0]$jps 3034NameNode 3233Jps 3193SecondaryNameNode 3110DataNode HDFS上测试创建目录、上传、下载文件 #HDFS上创建目录 [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/bin/hdfsdfs-mkdir/demo1 上传本地文件到HDFS上 [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/bin/hdfsdfs-put ${HADOOP_HOME}/etc/hadoop/core-site.xml/demo1 #读取HDFS上的文件内容 [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/bin/hdfsdfs-cat/demo1/core-site.xm #从HDFS上下载文件到本地 [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-get/demo1/core-site.xml 配置、启动YARN #配置mapred-site.xml,默认没有mapred-site.xml文件,但是有个mapred-site.xml.template配置模板文件。复制模板生成mapred-site.xml。 [hadoop@bigdata-senior01hadoop-2.5.0]#cpetc/hadoop/mapred-site.xml.templateetc/hadoop/mapred-site.xml #添加配置如下: <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> #指定mapreduce运行在yarn框架上。 #配置yarn-site.xml添加配置如下: <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>bigdata-senior01.chybinmy.com</value> </property> yarn.nodemanager.aux-services配置了yarn的默认混洗方式,选择为mapreduce的默认混洗算法。 yarn.resourcemanager.hostname指定了Resourcemanager运行在哪个节点上。 #启动Resourcemanager [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/sbin/yarn-daemon.shstartresourcemanager #启动nodemanager [hadoop@bigdata-senior01hadoop-2.5.0]$${HADOOP_HOME}/sbin/yarn-daemon.shstartnodemanager #查看是否启动成功 [hadoop@bigdata-senior01hadoop-2.5.0]$jps 3034NameNode 4439NodeManager 4197ResourceManager 4543Jps 3193SecondaryNameNode 3110DataNode #可以看到ResourceManager、NodeManager已经启动成功了。 YARN的Web页面 YARN的Web客户端端口号是8088,通过http://192.168.100.10:8088/可以查看。 运行MapReduce Job #创建测试用的Input文件,创建输入目录: [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-mkdir-p/wordcountdemo/input #创建原始文件:在本地/opt/data目录创建一个文件wc.input,内容如下。 #将wc.input文件上传到HDFS的/wordcountdemo/input目录中: [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-put/opt/data/wc.input/wordcountdemo/input #运行WordCountMapReduceJob [hadoop@bigdata-senior01hadoop-2.5.0]$bin/yarnjarshare/hadoop/mapreduce/hadoop-mapreduce-examples- 2.5.0.jarwordcount/wordcountdemo/input/wordcountdemo/output #查看输出结果目录 [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-ls/wordcountdemo/output -rw-r--r--1hadoopsupergroup02016-07-0505:12/wordcountdemo/output/_SUCCESS -rw-r--r--1hadoopsupergroup602016-07-0505:12/wordcountdemo/output/part-r-00000 #output目录中有两个文件,_SUCCESS文件是空文件,有这个文件说明Job执行成功。part-r-00000文件是结果文件,其中-r-说明这个文件是Reduce阶段产生的结果,mapreduce程序执行时,可以没有reduce阶段,但是肯定会有map阶段,如果没有reduce阶段这个地方有是-m-。一个reduce会产生一个part-r-开头的文件。查看输出文件内容。 [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-cat/wordcountdemo/output/part-r-00000 hadoop3 hbase1 hive2 mapreduce1 spark2 sqoop1 storm1 #结果是按照键值排好序的。 停止Hadoop [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/hadoop-daemon.shstopnamenode stoppingnamenode [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/hadoop-daemon.shstopdatanode stoppingdatanode [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/yarn-daemon.shstopresourcemanager stoppingresourcemanager [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/yarn-daemon.shstopnodemanager stoppingnodemanager Hadoop各个功能模块的理解 1、 HDFS模块 HDFS负责大数据的存储,通过将大文件分块后进行分布式存储方式,突破了服务器硬盘大小的限制,解决了单台机器无法存储大文件的问题,HDFS是个相对独立的模块,可以为YARN提供服务,也可以为HBase等其他模块提供服务。 2、 YARN模块 YARN是一个通用的资源协同和任务调度框架,是为了解决Hadoop1.x中MapReduce里NameNode负载太大和其他问题而创建的一个框架。YARN是个通用框架,不止可以运行MapReduce,还可以运行Spark、Storm等其他计算框架。 3、 MapReduce模块 MapReduce是一个计算框架,它给出了一种数据处理的方式,即通过Map阶段、Reduce阶段来分布式地流式处理数据。它只适用于大数据的离线处理,对实时性要求很高的应用不适用。 开启历史服务 [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/mr-jobhistory-daemon.shstarthistoryserver 开启后,可以通过Web页面查看历史服务器: http://bigdata-senior01.chybinmy.com:19888/ Web查看job执行历史 运行一个mapreduce任务 [hadoop@bigdata-senior01hadoop-2.5.0]$bin/yarnjarshare/hadoop/mapreduce/hadoop-mapreduce-examples- 2.5.0.jarwordcount/wordcountdemo/input/wordcountdemo/output1 #job执行中 #查看job历史 历史服务器的Web端口默认是19888,可以查看Web界面。但是在上面所显示的某一个Job任务页面的最下面,Map和Reduce个数的链接上,点击进入Map的详细信息页面,再查看某一个Map或者Reduce的详细日志是看不到的,是因为没有开启日志聚集服务。 开启日志聚集 日志聚集介绍 MapReduce是在各个机器上运行的,在运行过程中产生的日志存在于各个机器上,为了能够统一查看各个机器的运行日志,将日志集中存放在HDFS上,这个过程就是日志聚集。 开启日志聚集 #配置日志聚集功能:Hadoop默认是不启用日志聚集的。在yarn-site.xml文件里配置启用日志聚集。 <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <property> <name>yarn.log-aggregation.retain-seconds</name> <value>106800</value> </property> yarn.log-aggregation-enable:是否启用日志聚集功能。 yarn.log-aggregation.retain-seconds:设置日志保留时间,单位是秒。 #将配置文件分发到其他节点: [hadoop@bigdata-senior01hadoop]$scp/opt/modules/hadoop-2.5.0/etc/hadoop/yarn-site.xmlbigdata-senior02.chybinmy.com:/opt/modules/hadoop-2.5.0/etc/hadoop/ [hadoop@bigdata-senior01hadoop]$scp/opt/modules/hadoop-2.5.0/etc/hadoop/yarn-site.xmlbigdata-senior03.chybinmy.com:/opt/modules/hadoop-2.5.0/etc/hadoop/ #重启Yarn进程: [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/stop-yarn.sh [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/start-yarn.sh #重启HistoryServer进程: [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/mr-jobhistory-daemon.shstophistoryserver [hadoop@bigdata-senior01hadoop-2.5.0]$sbin/mr-jobhistory-daemon.shstarthistoryserver #测试日志聚集,运行一个demoMapReduce,使之产生日志: bin/yarnjarshare/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jarwordcount/input/output1 #查看日志:运行Job后,就可以在历史服务器Web页面查看各个Map和Reduce的日志了。 第四部分:完全分布式安装 完全布式环境部署Hadoop 完全分部式是真正利用多台Linux主机来进行部署Hadoop,对Linux机器集群进行规划,使得Hadoop各个模块分别部署在不同的多台机器上。 服务器功能规划 bigdata-senior01.chybinmy.com bigdata-senior02.chybinmy.com bigdata-senior03.chybinmy.com NameNode ResourceManage DataNode DataNode DataNode NodeManager NodeManager NodeManager HistoryServer SecondaryNameNode 在第一台机器上安装新的Hadoop 为了和之前BigData01机器上安装伪分布式Hadoop区分开来,我们将BigData01上的Hadoop服务都停止掉,然后在一个新的目录/opt/modules/app下安装另外一个Hadoop。 我们采用先在第一台机器上解压、配置Hadoop,然后再分发到其他两台机器上的方式来安装集群。 解压Hadoop目录 [hadoop@bigdata-senior01modules]$tar-zxf/opt/sofeware/hadoop-2.5.0.tar.gz-C/opt/modules/app/ #配置HadoopJDK路径修改hadoop-env.sh、mapred-env.sh、yarn-env.sh文件中的JDK路径: exportJAVA_HOME="/opt/modules/jdk1.7.0_67" 配置core-site.xml [hadoop@bigdata-senior01hadoop-2.5.0]$vimetc/hadoop/core-site.xml <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://bigdata-senior01.chybinmy.com:8020</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/modules/app/hadoop-2.5.0/data/tmp</value> </property> </configuration> #fs.defaultFS为NameNode的地址。hadoop.tmp.dir为hadoop临时目录的地址,默认情况下,NameNode和DataNode的数据文件都会存在这个目录下的对应子目录下。应该保证此目录是存在的,如果不存在,先创建。 配置hdfs-site.xml [hadoop@bigdata-senior01hadoop-2.5.0]$vimetc/hadoop/hdfs-site.xml <configuration> <property> <name>dfs.namenode.secondary.http-address</name> <value>bigdata-senior03.chybinmy.com:50090</value> </property> </configuration> #dfs.namenode.secondary.http-address是指定secondaryNameNode的http访问地址和端口号,因为在规划中,我们将BigData03规划为SecondaryNameNode服务器。所以这里设置为:bigdata-senior03.chybinmy.com:50090 配置slaves [hadoop@bigdata-senior01hadoop-2.5.0]$vimetc/hadoop/slaves bigdata-senior01.chybinmy.com bigdata-senior02.chybinmy.com bigdata-senior03.chybinmy.com #slaves文件是指定HDFS上有哪些DataNode节点。 配置yarn-site.xml [hadoop@bigdata-senior01hadoop-2.5.0]$vimetc/hadoop/yarn-site.xml 1 <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>bigdata-senior02.chybinmy.com</value> </property> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <property> <name>yarn.log-aggregation.retain-seconds</name> <value>106800</value> </property> #根据规划yarn.resourcemanager.hostname这个指定resourcemanager服务器指向bigdata-senior02.chybinmy.com。yarn.log-aggregation-enable是配置是否启用日志聚集功能。yarn.log-aggregation.retain-seconds是配置聚集的日志在HDFS上最多保存多长时间。 配置mapred-site.xml #从mapred-site.xml.template复制一个mapred-site.xml文件。 [hadoop@bigdata-senior01hadoop-2.5.0]$cpetc/hadoop/mapred-site.xml.templateetc/hadoop/mapred-site.xml 1 <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>bigdata-senior01.chybinmy.com:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>bigdata-senior01.chybinmy.com:19888</value> </property> </configuration> #mapreduce.framework.name设置mapreduce任务运行在yarn上。mapreduce.jobhistory.address是设置mapreduce的历史服务器安装在BigData01机器上。mapreduce.jobhistory.webapp.address是设置历史服务器的web页面地址和端口号。 设置SSH无密码登录 Hadoop集群中的各个机器间会相互地通过SSH访问,每次访问都输入密码是不现实的,所以要配置各个机器间的SSH是无密码登录的。 #在BigData01上生成公钥 [hadoop@bigdata-senior01hadoop-2.5.0]$ssh-keygen-trsa 一路回车,都设置为默认值,然后再当前用户的Home目录下的.ssh目录中会生成公钥文件(id_rsa.pub)和私钥文件(id_rsa)。 #分发公钥 [hadoop@bigdata-senior01hadoop-2.5.0]$ssh-copy-idbigdata-senior01.chybinmy.com [hadoop@bigdata-senior01hadoop-2.5.0]$ssh-copy-idbigdata-senior02.chybinmy.com [hadoop@bigdata-senior01hadoop-2.5.0]$ssh-copy-idbigdata-senior03.chybinmy.com #设置BigData02、BigData03到其他机器的无密钥登录,同样的在BigData02、BigData03上生成公钥和私钥后,将公钥分发到三台机器上。 分发Hadoop文件 #首先在其他两台机器上创建存放Hadoop的目录 [hadoop@bigdata-senior02~]$mkdir/opt/modules/app [hadoop@bigdata-senior03~]$mkdir/opt/modules/app #通过Scp分发 Hadoop根目录下的share/doc目录是存放的hadoop的文档,文件相当大,建议在分发之前将这个目录删除掉,可以节省硬盘空间并能提高分发的速度。doc目录大小有1.6G。 [hadoop@bigdata-senior01hadoop-2.5.0]$du-sh/opt/modules/app/hadoop-2.5.0/share/doc 1.6G/opt/modules/app/hadoop-2.5.0/share/doc [hadoop@bigdata-senior01hadoop-2.5.0]$scp-r/opt/modules/app/hadoop-2.5.0/bigdata-senior02.chybinmy.com:/opt/modules/app [hadoop@bigdata-senior01hadoop-2.5.0]$scp-r/opt/modules/app/hadoop-2.5.0/bigdata-senior03.chybinmy.com:/opt/modules/app 格式NameNode #在NameNode机器上执行格式化: [hadoop@bigdata-senior01hadoop-2.5.0]$/opt/modules/app/hadoop-2.5.0/bin/hdfsnamenode–format 注意:如果需要重新格式化NameNode,需要先将原来NameNode和DataNode下的文件全部删除,不然会报错,NameNode和DataNode所在目录是在core-site.xml中hadoop.tmp.dir、dfs.namenode.name.dir、dfs.datanode.data.dir属性配置的。 <property> <name>hadoop.tmp.dir</name> <value>/opt/data/tmp</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file://${hadoop.tmp.dir}/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file://${hadoop.tmp.dir}/dfs/data</value> </property> #因为每次格式化,默认是创建一个集群ID,并写入NameNode和DataNode的VERSION文件中(VERSION文件所在目录为dfs/name/current和dfs/data/current),重新格式化时,默认会生成一个新的集群ID,如果不删除原来的目录,会导致namenode中的VERSION文件中是新的集群ID,而DataNode中是旧的集群ID,不一致时会报错。另一种方法是格式化时指定集群ID参数,指定为旧的集群ID。 启动集群 #启动HDFS [hadoop@bigdata-senior01hadoop-2.5.0]$/opt/modules/app/hadoop-2.5.0/sbin/start-dfs.sh #启动YARN [hadoop@bigdata-senior01hadoop-2.5.0]$/opt/modules/app/hadoop-2.5.0/sbin/start-yarn.sh #在BigData02上启动ResourceManager: [hadoop@bigdata-senior02hadoop-2.5.0]$sbin/yarn-daemon.shstartresourcemanager #启动日志服务器 因为我们规划的是在BigData03服务器上运行MapReduce日志服务,所以要在BigData03上启动。 [hadoop@bigdata-senior03~]$/opt/modules/app/hadoop-2.5.0/sbin/mr-jobhistory-daemon.shstarthistoryserver startinghistoryserver,loggingto/opt/modules/app/hadoop-2.5.0/logs/mapred-hadoop-historyserver-bigdata-senior03.chybinmy.com.out [hadoop@bigdata-senior03~]$jps 3570Jps 3537JobHistoryServer 3310SecondaryNameNode 3213DataNode 3392NodeManager #查看HDFSWeb页面 http://bigdata-senior01.chybinmy.com:50070/ #查看YARNWeb页面 http://bigdata-senior02.chybinmy.com:8088/cluster 测试Job 我们这里用hadoop自带的wordcount例子来在本地模式下测试跑mapreduce。 #准备mapreduce输入文件wc.input [hadoop@bigdata-senior01modules]$cat/opt/data/wc.input hadoopmapreducehive hbasesparkstorm sqoophadoophive sparkhadoop #在HDFS创建输入目录input [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-mkdir/input #将wc.input上传到HDFS [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-put/opt/data/wc.input/input/wc.input #运行hadoop自带的mapreduceDemo [hadoop@bigdata-senior01hadoop-2.5.0]$bin/yarnjarshare/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jarwordcount/input/wc.input/output #查看输出文件 [hadoop@bigdata-senior01hadoop-2.5.0]$bin/hdfsdfs-ls/output Found2items -rw-r--r--3hadoopsupergroup02016-07-1416:36/output/_SUCCESS -rw-r--r--3hadoopsupergroup602016-07-1416:36/output/part-r-00000 程序员学习交流群:878249276,欢迎一到五年的工程师加入,合理利用自己每一分每一秒的时间来学习提 升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

优秀的个人博客,低调大师

Django 搭建CMDB系统完整[14](运维记录)

templates/search_yunweijilu.html {% extends 'base.html' %} {% block title %} <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.pack.js"></script> <link rel="stylesheet" type="text/css" href="/static/style/authority/jquery.fancybox-1.3.4.css" media="screen"></link> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> <script src="/static/scripts/datetime/jquery-ui-1.12.1/jquery-ui.min.js"></script> <link href="/static/scripts/datetime/jquery-ui-1.12.1/jquery-ui.min.css" rel="stylesheet" /> <script src="/static/scripts/datetime/jQuery-Timepicker/dist/jquery-ui-timepicker-addon.min.js"></script> <script type="text/javascript" src="/static/scripts/datetime/jQuery-Timepicker/dist/i18n/jquery-ui-timepicker-zh-CN.js"></script> <link href="/static/scripts/datetime/jQuery-Timepicker/dist/jquery-ui-timepicker-addon.min.css" rel="stylesheet" /> <script type="text/javascript"> (function($) { $(function() { $.datepicker.regional['zh-CN'] = { changeMonth: true, changeYear: true, clearText: '清除', clearStatus: '清除已选日期', closeText: '关闭', closeStatus: '不改变当前选择', prevText: '<上月', prevStatus: '显示上月', prevBigText: '<<', prevBigStatus: '显示上一年', nextText: '下月>', nextStatus: '显示下月', nextBigText: '>>', nextBigStatus: '显示下一年', currentText: '今天', currentStatus: '显示本月', monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], monthStatus: '选择月份', yearStatus: '选择年份', weekHeader: '周', weekStatus: '年内周次', dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'], dayNamesShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], dayNamesMin: ['日', '一', '二', '三', '四', '五', '六'], dayStatus: '设置 DD 为一周起始', dateStatus: '选择 m月 d日, DD', dateFormat: 'yy-mm-dd', firstDay: 1, initStatus: '请选择日期', isRTL: false }; }); $(function() { $.datepicker.setDefaults($.datepicker.regional['zh-CN']); $("#kssj").datetimepicker(); $("#jssj").datetimepicker(); }); }(jQuery)); </script> <div id="container"> <div class="ui_content"> <div class="ui_text_indent"> <div id="box_border"> <div id="box_top">搜索</div> 问题描述<input type="text" id="wtms" name="wtms" value="{{ wtms }}" class="ui_input_txt03" /> 问题来源<input type="text" id="wtly" name="wtly" value="{{ wtly }}" class="ui_input_txt03" style="width:50px" /> 处理人<input type="text" id="clr" name="clr" value="{{ clr }}" class="ui_input_txt03" style="width:50px" /> 开始时间<input type="text" id="kssj" name="kssj" value="{{ kssj|date:"Y-m-d H:i" }}" class="ui_input_txt03" style="width:70px" /> 结束时间<input type="text" id="jssj" name="jssj" value="{{ jssj|date:"Y-m-d H:i" }}" class="ui_input_txt03" style="width:70px" /> 类型 <select id="type" name="type" class="ui_select02"> <option value=100 selected = "selected">所有</option> <option value=0 {% if type == 0 %} selected = "selected" {% endif %}>日常巡检</option> <option value=1 {% if type == 1 %} selected = "selected" {% endif %}>网络设备配置</option> <option value=2 {% if type == 2 %} selected = "selected" {% endif %}>安全设备配置</option> <option value=3 {% if type == 3 %} selected = "selected" {% endif %}>系统部署</option> <option value=4 {% if type == 4 %} selected = "selected" {% endif %}>安全运维</option> <option value=5 {% if type == 5 %} selected = "selected" {% endif %}>系统更新/维护</option> <option value=6 {% if type == 6 %} selected = "selected" {% endif %}>系统重启</option> <option value=7 {% if type == 7 %} selected = "selected" {% endif %}>系统迁移</option> <option value=8 {% if type == 8 %} selected = "selected" {% endif %}>系统扩容</option> <option value=9 {% if type == 9 %} selected = "selected" {% endif %}>技术支持</option> </select> 机房<select id="machinaroom" name="machinaroom" class="ui_select02" > <option value=100 selected = "selected">所有</option> {% for mr in machinaroomlist %} <option value={{ mr.id }} {% if mr.id == machinaroom %} selected = "selected" {% endif %}>{{ mr.name }}</option> {% endfor %} </select> </div> <div id="box_bottom"> <div class="pagination"> <span class="current"> {% if yunweijilulist.has_previous %} <a href="javascript:void(0)" onclick="search_yunweijilu({{ yunweijilulist.previous_page_number }});">上一页</a> {% endif %} <span class="current"> Page {{ yunweijilulist.number }} of {{ yunweijilulist.paginator.num_pages }}. </span> {% if yunweijilulist.has_next %} <a href="javascript:void(0)" onclick="search_yunweijilu({{ yunweijilulist.next_page_number }});">下一页</a> {% endif %} </span> </div> <input type="button" value="查询" class="ui_input_btn01" onclick="search_yunweijilu(1);"/> <input type="button" value="新增" class="ui_input_btn01" onclick="add_yunweijilu();" /> <input type="button" value="删除" class="ui_input_btn01" onclick="batdel_yunweijilu();" /> <input type="button" value="导出EXCEL" class="ui_input_btn01" onclick="excel_yunweijilu();" /> </div> </form> </div> </div> {% endblock %} {% block content %} <div class="ui_content"> <div class="ui_tb"> <table class="table1" cellspacing="0" cellpadding="0" width="100%" align="center" border="0"> <tr> <th width="30"><input type="checkbox" id="id" name="id" /> </th> <th>类型</th> <th>问题描述</th> <th>问题来源</th> <th>接收时间</th> <th>处理人</th> <th>开始时间</th> <th>结束时间</th> <th>处理办法</th> <th>备注</th> <th>机房</th> <th>操作</th> </tr> {% for s in yunweijilulist.object_list %} <tr> <td><input type="checkbox" name="idcheck" value={{ s.id }} class="acb" /></td> <td> {% if s.type == 0 %} 日常巡检 {% elif s.type == 1 %} 网络设备配置 {% elif s.type == 2 %} 安全设备配置 {% elif s.type == 3 %} 系统部署 {% elif s.type == 4 %} 安全运维 {% elif s.type == 5 %} 系统更新/维护 {% elif s.type == 6 %} 系统重启 {% elif s.type == 7 %} 系统迁移 {% elif s.type == 8 %} 系统扩容 {% elif s.type == 9 %} 技术支持 {% endif %} </td> <td title="{{ s.wtms }}">{{ s.wtms|truncatechars:"8" }}</td> <td title="{{ s.wtly }}">{{ s.wtly|truncatechars:"8" }}</td> <td title="{{ s.wtjssj|date:"Y-m-d H:i" }}">{{ s.wtjssj|date:"Y-m-d" }}</td> <td title="{{ s.clr }}">{{ s.clr|truncatechars:"8" }}</td> <td title="{{ s.kssj|date:"Y-m-d H:i" }}">{{ s.kssj|date:"Y-m-d" }}</td> <td title="{{ s.jssj|date:"Y-m-d H:i" }}">{{ s.jssj|date:"Y-m-d" }}</td> <td title="{{ s.clbf }}">{{ s.clbf|truncatechars:"8" }}</td> <td title="{{ s.memo }}">{{ s.memo|truncatechars:"6"}}</td> <td title="{{ s.machinaroom.name }}">{{ s.machinaroom.name|truncatechars:"8"}}</td> <td> <a href="javascript:void(0)" onclick="edit_yunweijilu('{{ s.id }}')" class="edit">编辑</a> <a href="javascript:void(0)" onclick="del_yunweijilu({{ s.id }},{{ yunweijilulist.number }});">删除</a> </td> </tr> {% endfor %} </table> </div> </div> </div> <script type="text/javascript"> function search_yunweijilu(page){ var wtms = document.getElementById("wtms").value; var wtly = document.getElementById("wtly").value; var clr= document.getElementById("clr").value; var kssj= document.getElementById("kssj").value; var jssj = document.getElementById("jssj").value; var type = document.getElementById("type").value; var machinaroom = document.getElementById("machinaroom").value; var myurl="search_yunweijilu.html"+"?"+"wtms="+wtms+"&&wtly="+wtly+"&&clr="+clr+"&&kssj="+kssj+"&&jssj="+jssj+"&&type="+type+"&&machinaroom="+machinaroom+"&&page="+page; window.location.assign(encodeURI(myurl)) } function add_yunweijilu(){ var width = 400; var height = 500; var left = parseInt((screen.availWidth/2) - (width/2));//屏幕居中 var top = parseInt((screen.availHeight/2) - (height/2)); var windowFeatures = "width=" + width + ",height=" + height + ",status,resizable,left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top; newWindow = window.open("add_yunweijilu.html", "subWind", windowFeatures); } function edit_yunweijilu(id){ var width = 400; var height = 500; var left = parseInt((screen.availWidth/2) - (width/2));//屏幕居中 var top = parseInt((screen.availHeight/2) - (height/2)); var windowFeatures = "width=" + width + ",height=" + height + ",status,resizable,left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top; newWindow = window.open("edit_yunweijilu.html?id="+id, "subWind", windowFeatures); } function del_yunweijilu(id,page){ if(window.confirm('确定要删除该记录吗?')){ var wtms = document.getElementById("wtms").value; var wtly = document.getElementById("wtly").value; var clr= document.getElementById("clr").value; var kssj= document.getElementById("kssj").value; var jssj = document.getElementById("jssj").value; var type = document.getElementById("type").value; var machinaroom = document.getElementById("machinaroom").value; var myurl="del_yunweijilu.html"+"?"+"id="+id+"&&wtms="+wtms+"&&wtly="+wtly+"&&clr="+clr+"&&kssj="+kssj+"&&jssj="+jssj+"&&type="+type+"&&machinaroom="+machinaroom+"&&page="+page; window.location.assign(encodeURI(myurl)) return true; }else{ //alert("取消"); return false; } } function batdel_yunweijilu(){ if(window.confirm('确定要删除记录吗?')){ obj = document.getElementsByName("idcheck"); var wtms = document.getElementById("wtms").value; var wtly = document.getElementById("wtly").value; var clr= document.getElementById("clr").value; var kssj= document.getElementById("kssj").value; var jssj = document.getElementById("jssj").value; var type = document.getElementById("type").value; var machinaroom = document.getElementById("machinaroom").value; check_val = []; for(k in obj){ if(obj[k].checked) check_val.push(obj[k].value); } var myurl="batdel_yunweijilu.html"+"?"+"ids="+check_val+"&&wtms="+wtms+"&&wtly="+wtly+"&&clr="+clr+"&&kssj="+kssj+"&&jssj="+jssj+"&&type="+type+"&&machinaroom="+machinaroom; window.location.assign(encodeURI(myurl)) return true; }else{ return false; } } function excel_yunweijilu(){ var wtms = document.getElementById("wtms").value; var wtly = document.getElementById("wtly").value; var clr= document.getElementById("clr").value; var kssj= document.getElementById("kssj").value; var jssj = document.getElementById("jssj").value; var type = document.getElementById("type").value; var machinaroom = document.getElementById("machinaroom").value; var myurl="excel_yunweijilu.html"+"?"+"wtms="+wtms+"&&wtly="+wtly+"&&clr="+clr+"&&kssj="+kssj+"&&jssj="+jssj+"&&type="+type+"&&machinaroom="+machinaroom; window.location.assign(encodeURI(myurl)) } </script> {% endblock %} templates/add_yunweijilu.html <!DOCTYPE html> <html> <head> <title>CMDB</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script src="/static/scripts/My97DatePicker/WdatePicker.js" type="text/javascript" defer="defer"></script> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> <script src="/static/scripts/datetime/jquery-ui-1.12.1/jquery-ui.min.js"></script> <link href="/static/scripts/datetime/jquery-ui-1.12.1/jquery-ui.min.css" rel="stylesheet" /> <script src="/static/scripts/datetime/jQuery-Timepicker/dist/jquery-ui-timepicker-addon.min.js"></script> <script type="text/javascript" src="/static/scripts/datetime/jQuery-Timepicker/dist/i18n/jquery-ui-timepicker-zh-CN.js"></script> <link href="/static/scripts/datetime/jQuery-Timepicker/dist/jquery-ui-timepicker-addon.min.css" rel="stylesheet" /> <script type="text/javascript"> (function($) { $(function() { $.datepicker.regional['zh-CN'] = { changeMonth: true, changeYear: true, clearText: '清除', clearStatus: '清除已选日期', closeText: '关闭', closeStatus: '不改变当前选择', prevText: '<上月', prevStatus: '显示上月', prevBigText: '<<', prevBigStatus: '显示上一年', nextText: '下月>', nextStatus: '显示下月', nextBigText: '>>', nextBigStatus: '显示下一年', currentText: '今天', currentStatus: '显示本月', monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], monthStatus: '选择月份', yearStatus: '选择年份', weekHeader: '周', weekStatus: '年内周次', dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'], dayNamesShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], dayNamesMin: ['日', '一', '二', '三', '四', '五', '六'], dayStatus: '设置 DD 为一周起始', dateStatus: '选择 m月 d日, DD', dateFormat: 'yy-mm-dd', firstDay: 1, initStatus: '请选择日期', isRTL: false }; }); $(function() { $.datepicker.setDefaults($.datepicker.regional['zh-CN']); $("#yunweijiluwtjssj").datetimepicker(); $("#yunweijilukssj").datetimepicker(); $("#yunweijilujssj").datetimepicker(); }); }(jQuery)); </script> <form id="addyunweijiluform" name="addyunweijiluform" action="add_yunweijilu.html" method="post"> <div id="container"> <div id="nav_links"> 当前位置:运维管理><span style="color: #1A5CC6;">新增运维记录</span> <div id="page_close"> <a href="javascript:parent.$.fancybox.close();"> <img src="/static/images/common/page_close.png" width="20" height="20" style="vertical-align: text-top;"/> </a> </div> </div> <div class="ui_content"> <table cellspacing="0" cellpadding="0" width="100%" align="left" border="0"> <tr> <td class="ui_text_rt">类型:</td> <td class="ui_text_lt"> <select name="yunweijilutype" id="yunweijilutype" class="ui_select01" > <option value=0>日常巡检</option> <option value=1>网络设备配置</option> <option value=2>安全设备配置</option> <option value=3>系统部署</option> <option value=4>安全运维</option> <option value=5>系统更新/维护</option> <option value=6>系统重启</option> <option value=7>系统迁移</option> <option value=8>系统扩容</option> <option value=9>技术支持</option> </select> </td> </tr> <tr> <td class="ui_text_rt">问题描述:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluwtms" name="yunweijiluwtms" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">问题来源:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluwtly" name="yunweijiluwtly" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">问题接收时间:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluwtjssj" name="yunweijiluwtjssj" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">处理人:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluclr" name="yunweijiluclr" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">开始时间:</td> <td class="ui_text_lt"> <input type="text" id="yunweijilukssj" name="yunweijilukssj" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">结束时间:</td> <td class="ui_text_lt"> <input type="text" id="yunweijilujssj" name="yunweijilujssj" value="" class="ui_input_txt02" /> </td> </tr> <tr> </tr> <tr> <td class="ui_text_rt">处理办法:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluclbf" name="yunweijiluclbf" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">备注:</td> <td class="ui_text_lt"> <input type="text" id="yunweijilumemo" name="yunweijilumemo" value="" class="ui_input_txt02" /> </td> </tr> </tr> <tr> <td class="ui_text_rt">机房:</td> <td class="ui_text_lt"> <select name="yunweijilumachinaroom" id="yunweijilumachinaroom" class="ui_select01" > {% for mr in machinaroomlist %} <option value={{ mr.id }}>{{ mr.name }}</option> {% endfor %} </select> </td> </tr> <tr> <td>&nbsp;</td> <td class="ui_text_lt"> &nbsp;<input id="submitbutton" type="submit" value="提交" class="ui_input_btn01"/> &nbsp;<input id="cancelbutton" type="cancel" value="取消" class="ui_input_btn01"/> </td> </tr> </table> </div> </div> </form> </body> </html> templates/edit_yunweijilu.html <!DOCTYPE html> <html> <head> <title>CMDB</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script src="/static/scripts/My97DatePicker/WdatePicker.js" type="text/javascript" defer="defer"></script> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> <script src="/static/scripts/datetime/jquery-ui-1.12.1/jquery-ui.min.js"></script> <link href="/static/scripts/datetime/jquery-ui-1.12.1/jquery-ui.min.css" rel="stylesheet" /> <script src="/static/scripts/datetime/jQuery-Timepicker/dist/jquery-ui-timepicker-addon.min.js"></script> <script type="text/javascript" src="/static/scripts/datetime/jQuery-Timepicker/dist/i18n/jquery-ui-timepicker-zh-CN.js"></script> <link href="/static/scripts/datetime/jQuery-Timepicker/dist/jquery-ui-timepicker-addon.min.css" rel="stylesheet" /> <script type="text/javascript"> (function($) { $(function() { $.datepicker.regional['zh-CN'] = { changeMonth: true, changeYear: true, clearText: '清除', clearStatus: '清除已选日期', closeText: '关闭', closeStatus: '不改变当前选择', prevText: '<上月', prevStatus: '显示上月', prevBigText: '<<', prevBigStatus: '显示上一年', nextText: '下月>', nextStatus: '显示下月', nextBigText: '>>', nextBigStatus: '显示下一年', currentText: '今天', currentStatus: '显示本月', monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], monthStatus: '选择月份', yearStatus: '选择年份', weekHeader: '周', weekStatus: '年内周次', dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'], dayNamesShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], dayNamesMin: ['日', '一', '二', '三', '四', '五', '六'], dayStatus: '设置 DD 为一周起始', dateStatus: '选择 m月 d日, DD', dateFormat: 'yy-mm-dd', firstDay: 1, initStatus: '请选择日期', isRTL: false }; }); $(function() { $.datepicker.setDefaults($.datepicker.regional['zh-CN']); $("#yunweijiluwtjssj").datetimepicker(); $("#yunweijilukssj").datetimepicker(); $("#yunweijilujssj").datetimepicker(); }); }(jQuery)); </script> </head> <body> <form id="edityunweijiluform" name="edityunweijiluform" action="edit_yunweijilu.html" method="post"> <div id="container"> <div id="nav_links"> 当前位置:配置管理><span style="color: #1A5CC6;">编辑运维记录</span> <div id="page_close"> <a href="javascript:parent.$.fancybox.close();"> <img src="/static/images/common/page_close.png" width="20" height="20" style="vertical-align: text-top;"/> </a> </div> </div> <div class="ui_content"><input style="visibility:hidden" value={{ yunweijilu.id }} type="text" name="id" id="id" /> <table cellspacing="0" cellpadding="0" width="100%" align="left" border="0"> <tr> <td class="ui_text_rt">类型:</td> <td class="ui_text_lt"> <select name="yunweijilutype" id="yunweijilutype" class="ui_select01" > <option value=0 {% if yunweijilu.type == 0 %} selected="selected" {% endif %}>日常巡检</option> <option value=1 {% if yunweijilu.type == 1 %} selected="selected" {% endif %}>网络设备配置</option> <option value=2 {% if yunweijilu.type == 2 %} selected="selected" {% endif %}>安全设备配置</option> <option value=3 {% if yunweijilu.type == 3 %} selected="selected" {% endif %}>系统部署</option> <option value=4 {% if yunweijilu.type == 4 %} selected="selected" {% endif %}>安全运维</option> <option value=5 {% if yunweijilu.type == 5 %} selected="selected" {% endif %}>系统更新/维护</option> <option value=6 {% if yunweijilu.type == 6 %} selected="selected" {% endif %}>系统重启</option> <option value=7 {% if yunweijilu.type == 7 %} selected="selected" {% endif %}>系统迁移</option> <option value=8 {% if yunweijilu.type == 8 %} selected="selected" {% endif %}>系统扩容</option> <option value=9 {% if yunweijilu.type == 9 %} selected="selected" {% endif %}>技术支持</option> </select> </td> </tr> <tr> <td class="ui_text_rt">问题描述:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluwtms" name="yunweijiluwtms" value="{{ yunweijilu.wtms }}" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">问题来源:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluwtly" name="yunweijiluwtly" value="{{ yunweijilu.wtly }}" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">问题接收时间:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluwtjssj" name="yunweijiluwtjssj" value="{{ yunweijilu.wtjssj|date:"Y-m-d H:i" }}" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">处理人:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluclr" name="yunweijiluclr" value="{{ yunweijilu.clr }}" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">开始时间:</td> <td class="ui_text_lt"> <input type="text" id="yunweijilukssj" name="yunweijilukssj" value="{{ yunweijilu.kssj|date:"Y-m-d H:i" }}" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">结束时间:</td> <td class="ui_text_lt"> <input type="text" id="yunweijilujssj" name="yunweijilujssj" value="{{ yunweijilu.jssj|date:"Y-m-d H:i" }}" class="ui_input_txt02" /> </td> </tr> <tr> </tr> <tr> <td class="ui_text_rt">处理办法:</td> <td class="ui_text_lt"> <input type="text" id="yunweijiluclbf" name="yunweijiluclbf" value="{{ yunweijilu.clbf }}" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">备注:</td> <td class="ui_text_lt"> <input type="text" id="yunweijilumemo" name="yunweijilumemo" value="{{ yunweijilu.memo }}" class="ui_input_txt02" /> </td> </tr> </tr> <tr> <td class="ui_text_rt">机房:</td> <td class="ui_text_lt"> <select name="yunweijilumachinaroom" id="yunweijilumachinaroom" class="ui_select01" > {% for mr in machinaroomlist %} <option value={{ mr.id }} {% if yunweijilu.machinaroom.id == mr.id %} selected="selected" {% endif %}>{{ mr.name }}</option> {% endfor %} </select> </td> </tr> <tr> <td>&nbsp;</td> <td class="ui_text_lt"> &nbsp;<input id="submitbutton" type="submit" value="提交" class="ui_input_btn01"/> &nbsp;<input id="cancelbutton" type="cancel" value="取消" class="ui_input_btn01"/> </td> </tr> </table> </div> </div> </form> </body> </html>

优秀的个人博客,低调大师

Django 搭建CMDB系统完整[12](软件资产、厂商)

search_software.html {% extends 'base.html' %} {% block title %} <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.pack.js"></script> <link rel="stylesheet" type="text/css" href="/static/style/authority/jquery.fancybox-1.3.4.css" media="screen"></link> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> <div id="container"> <div class="ui_content"> <div class="ui_text_indent"> <div id="box_border"> <div id="box_top">搜索</div> 软件名字<input type="text" id="mname" name="mname" value="{{ mname }}" class="ui_input_txt02" /> </div> <div id="box_top">新增/编辑</div> <form id="submitForm" name="submitForm" method="post" action="add_software.html"> <input type="hidden" id="softwareid" name="softwareid"/> 软件名字<input type="text" id="softwarename" name="softwarename" class="ui_input_txt02" /> 授权数<input type="text" id="softwarelicense_num" name="softwarelicense_num" class="ui_input_txt02" /> 版本号<input type="text" id="softwareversion" name="softwareversion" class="ui_input_txt02" /> </div> <div id="box_bottom"> <div class="pagination"> <span class="current"> {% if softwarelist.has_previous %} <a href="javascript:void(0)" onclick="search_software({{ softwarelist.previous_page_number }});">上一页</a> {% endif %} <span class="current"> Page {{ softwarelist.number }} of {{ softwarelist.paginator.num_pages }}. </span> {% if softwarelist.has_next %} <a href="javascript:void(0)" onclick="search_software({{ softwarelist.next_page_number }});">下一页</a> {% endif %} </span> </div> <input type="button" value="查询" class="ui_input_btn01" onclick="search_software(1);"/> <input type="submit" value="新增" class="ui_input_btn01" /> <input type="button" value="编辑" class="ui_input_btn01" onclick="edit_software({{ softwarelist.number }});" /> <input type="button" value="删除" class="ui_input_btn01" onclick="batdel_software();" /> <input type="button" value="导出EXCEL" class="ui_input_btn01" onclick="excel_software();" /> </div> </form> </div> </div> {% endblock %} {% block content %} <div class="ui_content"> <div class="ui_tb"> <table class="table" cellspacing="0" cellpadding="0" width="100%" align="center" border="0"> <tr> <th width="30"><input type="checkbox" id="id" name="id" /> </th> <th>软件名字</th> <th>授权数</th> <th>版本号</th> <th>操作</th> </tr> {% for mr in softwarelist.object_list %} <tr> <td><input type="checkbox" name="idcheck" value={{ mr.id }} class="acb" /></td> <td>{{ mr.name }}</td> <td>{{ mr.license_num }}</td> <td>{{ mr.version }}</td> <td> <a href="javascript:void(0)" onclick="edit_mr('{{ mr.id }}','{{ mr.name }}','{{ mr.license_num }}','{{ mr.version }}')" class="edit">编辑</a> <a href="javascript:void(0)" onclick="del_software({{ mr.id }},{{ softwarelist.number }});">删除</a> </td> </tr> {% endfor %} </table> </div> </div> </div> <script type="text/javascript"> function search_software(page){ var text1 = document.getElementById("mname").value; var myurl="search_software.html"+"?"+"mname="+text1+"&&page="+page; window.location.assign(encodeURI(myurl)) } function edit_mr(id,name,license_num,version){ document.getElementById("softwareid").value=id; document.getElementById("softwarename").value=name; document.getElementById("softwarelicense_num").value=license_num; document.getElementById("softwareversion").value=version; } function edit_software(page){ var text1 = document.getElementById("mname").value; id=document.getElementById("softwareid").value; name=document.getElementById("softwarename").value; license_num=document.getElementById("softwarelicense_num").value; version=document.getElementById("softwareversion").value; var myurl="edit_software.html"+"?"+"id="+id+"&&name="+name+"&&license_num="+license_num+"&&version="+version+"&&mname="+text1+"&&page="+page; window.location.assign(encodeURI(myurl)) } function del_software(id,page){ if(window.confirm('确定要删除该记录吗?')){ var text1= document.getElementById("mname").value; var myurl="del_software.html"+"?"+"id="+id+"&&mname="+text1+"&&page="+page; window.location.assign(encodeURI(myurl)) return true; }else{ //alert("取消"); return false; } } function batdel_software(){ if(window.confirm('确定要删除记录吗?')){ obj = document.getElementsByName("idcheck"); var text1= document.getElementById("mname").value; check_val = []; for(k in obj){ if(obj[k].checked) check_val.push(obj[k].value); } var myurl="batdel_software.html"+"?"+"ids="+check_val+"&&mname="+text1; window.location.assign(encodeURI(myurl)) return true; }else{ return false; } } function excel_software(){ var text1 = document.getElementById("mname").value; var myurl="excel_software.html"+"?"+"mname="+text1; window.location.assign(encodeURI(myurl)) } </script> {% endblock %} search_manufactory.html {% extends 'base.html' %} {% block title %} <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.pack.js"></script> <link rel="stylesheet" type="text/css" href="/static/style/authority/jquery.fancybox-1.3.4.css" media="screen"></link> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> <div id="container"> <div class="ui_content"> <div class="ui_text_indent"> <div id="box_border"> <div id="box_top">搜索</div> 厂商名字<input type="text" id="mname" name="mname" value="{{ mname }}" class="ui_input_txt02" /> </div> <div id="box_top">新增/编辑</div> <form id="submitForm" name="submitForm" method="post" action="add_manufactory.html"> <input type="hidden" id="manufactoryid" name="manufactoryid"/> 厂商名字<input type="text" id="manufactorymanufactory" name="manufactorymanufactory" class="ui_input_txt02" /> 厂商电话<input type="text" id="manufactorysupport_num" name="manufactorysupport_num" class="ui_input_txt02" /> 备注<input type="text" id="manufactorymemo" name="manufactorymemo" class="ui_input_txt02" /> </div> <div id="box_bottom"> <div class="pagination"> <span class="current"> {% if manufactorylist.has_previous %} <a href="javascript:void(0)" onclick="search_manufactory({{ manufactorylist.previous_page_number }});">上一页</a> {% endif %} <span class="current"> Page {{ manufactorylist.number }} of {{ manufactorylist.paginator.num_pages }}. </span> {% if manufactorylist.has_next %} <a href="javascript:void(0)" onclick="search_manufactory({{ manufactorylist.next_page_number }});">下一页</a> {% endif %} </span> </div> <input type="button" value="查询" class="ui_input_btn01" onclick="search_manufactory(1);"/> <input type="submit" value="新增" class="ui_input_btn01" /> <input type="button" value="编辑" class="ui_input_btn01" onclick="edit_manufactory({{ manufactorylist.number }});" /> <input type="button" value="删除" class="ui_input_btn01" onclick="batdel_manufactory();" /> <input type="button" value="导出EXCEL" class="ui_input_btn01" onclick="excel_manufactory();" /> </div> </form> </div> </div> {% endblock %} {% block content %} <div class="ui_content"> <div class="ui_tb"> <table class="table" cellspacing="0" cellpadding="0" width="100%" align="center" border="0"> <tr> <th width="30"><input type="checkbox" id="id" name="id" /> </th> <th>厂商名字</th> <th>厂商电话</th> <th>备注</th> <th>操作</th> </tr> {% for mr in manufactorylist.object_list %} <tr> <td><input type="checkbox" name="idcheck" value={{ mr.id }} class="acb" /></td> <td>{{ mr.manufactory }}</td> <td>{{ mr.support_num }}</td> <td>{{ mr.memo }}</td> <td> <a href="javascript:void(0)" onclick="edit_mr('{{ mr.id }}','{{ mr.manufactory }}','{{ mr.support_num }}','{{ mr.memo }}')" class="edit">编辑</a> <a href="javascript:void(0)" onclick="del_manufactory({{ mr.id }},{{ manufactorylist.number }});">删除</a> </td> </tr> {% endfor %} </table> </div> </div> </div> <script type="text/javascript"> function search_manufactory(page){ var text1 = document.getElementById("mname").value; var myurl="search_manufactory.html"+"?"+"mname="+text1+"&&page="+page; window.location.assign(encodeURI(myurl)) } function edit_mr(id,name,license_num,version){ document.getElementById("manufactoryid").value=id; document.getElementById("manufactorymanufactory").value=name; document.getElementById("manufactorysupport_num").value=license_num; document.getElementById("manufactorymemo").value=version; } function edit_manufactory(page){ var text1 = document.getElementById("mname").value; id=document.getElementById("manufactoryid").value; name=document.getElementById("manufactorymanufactory").value; license_num=document.getElementById("manufactorysupport_num").value; version=document.getElementById("manufactorymemo").value; var myurl="edit_manufactory.html"+"?"+"id="+id+"&&manufactory="+name+"&&support_num="+license_num+"&&memo="+version+"&&mname="+text1+"&&page="+page; window.location.assign(encodeURI(myurl)) } function del_manufactory(id,page){ if(window.confirm('确定要删除该记录吗?')){ var text1= document.getElementById("mname").value; var myurl="del_manufactory.html"+"?"+"id="+id+"&&mname="+text1+"&&page="+page; window.location.assign(encodeURI(myurl)) return true; }else{ //alert("取消"); return false; } } function batdel_manufactory(){ if(window.confirm('确定要删除记录吗?')){ obj = document.getElementsByName("idcheck"); var text1= document.getElementById("mname").value; check_val = []; for(k in obj){ if(obj[k].checked) check_val.push(obj[k].value); } var myurl="batdel_manufactory.html"+"?"+"ids="+check_val+"&&mname="+text1; window.location.assign(encodeURI(myurl)) return true; }else{ return false; } } function excel_manufactory(){ var text1 = document.getElementById("mname").value; var myurl="excel_manufactory.html"+"?"+"mname="+text1; window.location.assign(encodeURI(myurl)) } </script> {% endblock %} cmdbapp/softwareviews.py -- coding: utf-8 -- from future import unicode_literals from django.shortcuts import render,render_to_response from django.core.paginator import Paginator,InvalidPage,EmptyPage from cmdbapp.models import * from django.http import HttpResponse from django.http import HttpResponseRedirect from xlwt import * import StringIO def search_software(request): error = False each_page = 5 mname=request.GET.get('mname','0') if mname=='0' or mname.strip()=='': record_list = Software.objects.all() mname='' paginator = Paginator(record_list,each_page) try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 try: contacts = paginator.page(page) except (EmptyPage, InvalidPage): contacts = paginator.page(paginator.num_pages) return render_to_response('search_software.html',{'softwarelist':contacts,"mname":mname}) else: record_list = Software.objects.filter(name=mname) paginator = Paginator(record_list,each_page) try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 try: contacts = paginator.page(page) except (EmptyPage, InvalidPage): contacts = paginator.page(paginator.num_pages) return render_to_response('search_software.html',{'softwarelist':contacts,"mname":mname}) def add_software(request): n = request.POST.get('softwarename') v = request.POST.get('softwareversion') l = request.POST.get('softwarelicense_num') Software.objects.create(name=n,license_num=l,version=v) return HttpResponseRedirect('search_software.html') def edit_software(request): id=request.GET.get('id') iid=int(id) name=request.GET.get('name') l=request.GET.get('license_num') v=request.GET.get('version') Software.objects.filter(id=iid).update(name=name,license_num=l,version=v) page=request.GET.get('page') mname=request.GET.get('mname') return HttpResponseRedirect('search_software.html?mname='+mname+"&&page="+page) def del_software(request): id=request.GET.get('id') iid=int(id) Software.objects.filter(id=iid).delete() page=request.GET.get('page') mname=request.GET.get('mname') return HttpResponseRedirect('search_software.html?mname='+mname+"&&page="+page) def batdel_software(request): ids=request.GET.get('ids') b=ids.split(',') arr = map(int,b) for aaa in arr: Software.objects.filter(id=aaa).delete() mname=request.GET.get('mname') return HttpResponseRedirect('search_software.html?mname='+mname) def excel_software(request): mname=request.GET.get('mname','0') if mname=='0' or mname.strip()=='': list_obj = Software.objects.all() mname='' else: list_obj = Software.objects.filter(name=mname) if list_obj: # 创建工作薄 ws = Workbook(encoding='utf-8') w = ws.add_sheet(u"软件清单") w.write(0, 0, "id") w.write(0, 1, u"软件名字") w.write(0, 2, u"授权数") w.write(0, 3, u"版本号") # 写入数据 excel_row = 1 for obj in list_obj: data_id = obj.id data_name = obj.name data_license_num = obj.license_num data_version = obj.version w.write(excel_row, 0, data_id) w.write(excel_row, 1, data_name) w.write(excel_row, 2, data_license_num) w.write(excel_row, 3, data_version) excel_row += 1 sio = StringIO.StringIO() ws.save(sio) sio.seek(0) response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel') response['Content-Disposition'] = 'attachment; filename=机房清单-'+mname+'.xls' response.write(sio.getvalue()) return response cmdbapp/manufactoryviews.py -- coding: utf-8 -- from future import unicode_literals from django.shortcuts import render,render_to_response from django.core.paginator import Paginator,InvalidPage,EmptyPage from cmdbapp.models import * from django.http import HttpResponse from django.http import HttpResponseRedirect from xlwt import * import StringIO def search_manufactory(request): error = False each_page = 5 mname=request.GET.get('mname','0') if mname=='0' or mname.strip()=='': record_list = Manufactory.objects.all() mname='' paginator = Paginator(record_list,each_page) try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 try: contacts = paginator.page(page) except (EmptyPage, InvalidPage): contacts = paginator.page(paginator.num_pages) return render_to_response('search_manufactory.html',{'manufactorylist':contacts,"mname":mname}) else: record_list = Manufactory.objects.filter(name=mname) paginator = Paginator(record_list,each_page) try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 try: contacts = paginator.page(page) except (EmptyPage, InvalidPage): contacts = paginator.page(paginator.num_pages) return render_to_response('search_manufactory.html',{'manufactorylist':contacts,"mname":mname}) def add_manufactory(request): n = request.POST.get('manufactorymanufactory') v = request.POST.get('manufactorysupport_num') l = request.POST.get('manufactorymemo') Manufactory.objects.create(manufactory=n,support_num=v,memo=l) return HttpResponseRedirect('search_manufactory.html') def edit_manufactory(request): id=request.GET.get('id') iid=int(id) name=request.GET.get('manufactory') l=request.GET.get('support_num') v=request.GET.get('memo') Manufactory.objects.filter(id=iid).update(manufactory=name,support_num=l,memo=v) page=request.GET.get('page') mname=request.GET.get('mname') return HttpResponseRedirect('search_manufactory.html?mname='+mname+"&&page="+page) def del_manufactory(request): id=request.GET.get('id') iid=int(id) Manufactory.objects.filter(id=iid).delete() page=request.GET.get('page') mname=request.GET.get('mname') return HttpResponseRedirect('search_manufactory.html?mname='+mname+"&&page="+page) def batdel_manufactory(request): ids=request.GET.get('ids') b=ids.split(',') arr = map(int,b) for aaa in arr: Manufactory.objects.filter(id=aaa).delete() mname=request.GET.get('mname') return HttpResponseRedirect('search_manufactory.html?mname='+mname) def excel_manufactory(request): mname=request.GET.get('mname','0') if mname=='0' or mname.strip()=='': list_obj = Manufactory.objects.all() mname='' else: list_obj = Manufactory.objects.filter(name=mname) if list_obj: # 创建工作薄 ws = Workbook(encoding='utf-8') w = ws.add_sheet(u"厂商清单") w.write(0, 0, "id") w.write(0, 1, u"厂商名字") w.write(0, 2, u"电话") w.write(0, 3, u"备注") # 写入数据 excel_row = 1 for obj in list_obj: data_id = obj.id data_name = obj.manufactory data_license_num = obj.support_num data_version = obj.memo w.write(excel_row, 0, data_id) w.write(excel_row, 1, data_name) w.write(excel_row, 2, data_license_num) w.write(excel_row, 3, data_version) excel_row += 1 sio = StringIO.StringIO() ws.save(sio) sio.seek(0) response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel') response['Content-Disposition'] = 'attachment; filename=机房清单-'+mname+'.xls' response.write(sio.getvalue()) return response cmdb/urls.py """cmdb URL Configuration The urlpatterns list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from cmdbapp import machinaroomviews,serverviews,networkdeviceviews,securitydeviceviews,softwareviews,storagedeviceviews,manufactoryviews from django.contrib.auth.views import * from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib import staticfiles from django.views.static import serve urlpatterns = [ url(r'^static/(?P<path>.*)',machinaroomviews.main_page,name='main_page'), url(r'^base',machinaroomviews.base,name='base'), url(r'^search_machinaroom.html',machinaroomviews.add_machinaroom,name='add_machinaroom'), url(r'^edit_machinaroom.html',machinaroomviews.edit_machinaroom,name='edit_machinaroom'), url(r'^del_machinaroom.html',machinaroomviews.del_machinaroom,name='del_machinaroom'), url(r'^batdel_machinaroom.html',machinaroomviews.batdel_machinaroom,name='batdel_machinaroom'), url(r'^excel_machinaroom.html',machinaroomviews.excel_machinaroom,name='excel_machinaroom'), url(r'^login/',serverviews.search_server,name='search_server'), url(r'^add_server.html',serverviews.edit_server,name="edit_server"), url(r'^del_server.html',serverviews.del_server,name='del_server'), url(r'^batdel_server.html',serverviews.batdel_server,name='batdel_server'), url(r'^excel_server.html',serverviews.excel_server,name='excel_server'), url(r'^search_networkdevice.html',networkdeviceviews.add_networkdevice,name="add_networkdevice"), url(r'^edit_networkdevice.html',securitydeviceviews.search_securitydevice,name='search_securitydevice'), url(r'^add_securitydevice.html',securitydeviceviews.edit_securitydevice,name="edit_securitydevice"), url(r'^del_securitydevice.html',securitydeviceviews.del_securitydevice,name='del_securitydevice'), url(r'^batdel_securitydevice.html',securitydeviceviews.batdel_securitydevice,name='batdel_securitydevice'), url(r'^excel_securitydevice.html',securitydeviceviews.excel_securitydevice,name='excel_securitydevice'), url(r'^search_storagedevice.html',storagedeviceviews.add_storagedevice,name="add_storagedevice"), url(r'^edit_storagedevice.html',softwareviews.search_software,name='search_software'), url(r'^add_software.html',manufactoryviews.search_manufactory,name='search_manufactory'), url(r'^add_manufactory.html$',manufactoryviews.add_manufactory,name='add_manufactory'), url(r'^edit_manufactory.html',manufactoryviews.edit_manufactory,name='edit_manufactory'), url(r'^del_manufactory.html',manufactoryviews.del_manufactory,name='del_manufactory'), url(r'^batdel_manufactory.html',manufactoryviews.batdel_manufactory,name='batdel_manufactory'), url(r'^excel_manufactory.html',manufactoryviews.excel_manufactory,name='excel_manufactory'), ]

优秀的个人博客,低调大师

Django 搭建CMDB系统完整[11](服务器)

templates/add_server.html edit_server.html search_server.html <!DOCTYPE html> <html> <head> <title>CMDB</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script type="text/javascript" src="/static/scripts/jquery/jquery-1.4.4.min.js"></script> <script src="/static/scripts/My97DatePicker/WdatePicker.js" type="text/javascript" defer="defer"></script> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> </head> <body> <form id="addserverform" name="addserverform" action="add_server.html" method="post"> <div id="container"> <div id="nav_links"> 当前位置:服务器资产管理><span style="color: #1A5CC6;">新增服务器</span> <div id="page_close"> <a href="javascript:parent.$.fancybox.close();"> <img src="/static/images/common/page_close.png" width="20" height="20" style="vertical-align: text-top;"/> </a> </div> </div> <div class="ui_content"> <table cellspacing="0" cellpadding="0" width="100%" align="left" border="0"> <tr> <td class="ui_text_rt">主机名字</td> <td class="ui_text_lt"> <input type="text" id="serverhostname" name="serverhostname" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">制造商/型号</td> <td class="ui_text_lt"> <input type="text" id="servermodel" name="servermodel" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">IP</td> <td class="ui_text_lt"> <input type="text" id="serverip" name="serverip" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">操作系统</td> <td class="ui_text_lt"> <input type="text" id="serveros" name="serveros" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">CPU</td> <td class="ui_text_lt"> <input type="text" id="servercpu" name="servercpu" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">内存</td> <td class="ui_text_lt"> <input type="text" id="servermemory" name="servermemory" value="" class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">硬盘</td> <td class="ui_text_lt"> <input type="text" id="serverdisk" name="serverdisk" value="" class="ui_input_txt02" /> </td> </tr> <tr> </tr> <tr> <td class="ui_text_rt">状态</td> <td class="ui_text_lt"> <select name="serverstatus" id="serverstatus" class="ui_select01" > <option value=0>在线</option> <option value=1>已下线</option> <option value=2>未知</option> <option value=3>故障</option> <option value=4>备用</option> </select> </td> </tr> <tr> <td class="ui_text_rt">所属机房</td> <td class="ui_text_lt"> <select name="servermachinaroom" id="servermachinaroom" class="ui_select01"> {% for mr in machinaroomlist %} <option value={{ mr.id }}>{{ mr.name }}</option> {% endfor %} </select> </td> </tr> <tr> <td>&nbsp;</td> <td class="ui_text_lt"> &nbsp;<input id="submitbutton" type="submit" value="提交" class="ui_input_btn01"/> &nbsp;<input id="cancelbutton" type="cancel" value="取消" class="ui_input_btn01"/> </td> </tr> </table> </div> </div> </form> </body> </html> <!DOCTYPE html> <html> <head> <title>CMDB</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script type="text/javascript" src="/static/scripts/jquery/jquery-1.4.4.min.js"></script> <script src="/static/scripts/My97DatePicker/WdatePicker.js" type="text/javascript" defer="defer"></script> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> </head> <body> <form id="editserverform" name="editserverform" action="edit_server.html" method="post"> <div id="container"> <div id="nav_links"> 当前位置:服务器资产管理><span style="color: #1A5CC6;">编辑服务器</span> <div id="page_close"> <a href="javascript:parent.$.fancybox.close();"> <img src="/static/images/common/page_close.png" width="20" height="20" style="vertical-align: text-top;"/> </a> </div> </div> <div class="ui_content"><input style="visibility:hidden" value={{ server.id }} type="text" name="id" id="id" /> <table cellspacing="0" cellpadding="0" width="100%" align="left" border="0"> <tr> <td class="ui_text_rt">主机名字</td> <td class="ui_text_lt"> <input type="text" id="serverhostname" name="serverhostname" value={{ server.hostname }} class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">制造商/型号</td> <td class="ui_text_lt"> <input type="text" id="servermodel" name="servermodel" value={{ server.model }} class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">IP</td> <td class="ui_text_lt"> <input type="text" id="serverip" name="serverip" value={{ server.ip }} class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">操作系统</td> <td class="ui_text_lt"> <input type="text" id="serveros" name="serveros" value={{ server.os }} class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">CPU</td> <td class="ui_text_lt"> <input type="text" id="servercpu" name="servercpu" value={{ server.cpu }} class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">内存</td> <td class="ui_text_lt"> <input type="text" id="servermemory" name="servermemory" value={{ server.memory }} class="ui_input_txt02" /> </td> </tr> <tr> <td class="ui_text_rt">硬盘</td> <td class="ui_text_lt"> <input type="text" id="serverdisk" name="serverdisk" value={{ server.disk }} class="ui_input_txt02" /> </td> </tr> <tr> </tr> <tr> <td class="ui_text_rt">状态</td> <td class="ui_text_lt"> <select name="serverstatus" id="serverstatus" class="ui_select01" > <option value=0>在线</option> <option value=1>已下线</option> <option value=2>未知</option> <option value=3>故障</option> <option value=4>备用</option> </select> </td> </tr> <tr> <td class="ui_text_rt">所属机房</td> <td class="ui_text_lt"> <select name="servermachinaroom" id="servermachinaroom" class="ui_select01"> {% for mr in machinaroomlist %} <option value={{ mr.id }}>{{ mr.name }}</option> {% endfor %} </select> </td> </tr> <tr> <td>&nbsp;</td> <td class="ui_text_lt"> &nbsp;<input id="submitbutton" type="submit" value="提交" class="ui_input_btn01"/> &nbsp;<input id="cancelbutton" type="cancel" value="取消" class="ui_input_btn01"/> </td> </tr> </table> </div> </div> </form> </body> </html> {% extends 'base.html' %} {% block title %} <script type="text/javascript" src="/static/scripts/jquery/jquery-1.7.1.js"></script> <link href="/static/style/authority/basic_layout.css" rel="stylesheet" type="text/css"> <link href="/static/style/authority/common_style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/static/scripts/authority/commonAll.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.js"></script> <script type="text/javascript" src="/static/scripts/fancybox/jquery.fancybox-1.3.4.pack.js"></script> <link rel="stylesheet" type="text/css" href="/static/style/authority/jquery.fancybox-1.3.4.css" media="screen"></link> <script type="text/javascript" src="/static/scripts/artDialog/artDialog.js?skin=default"></script> <div id="container"> <div class="ui_content"> <div class="ui_text_indent"> <div id="box_border"> <div id="box_top">搜索</div> 机房名字<input type="text" id="mname" name="mname" value="{{ mname }}" class="ui_input_txt03" /> 主机名字<input type="text" id="sname" name="sname" value="{{ sname }}" class="ui_input_txt03" /> ip地址<input type="text" id="ip" name="ip" value="{{ ip }}" class="ui_input_txt03" /> 操作系统<input type="text" id="os" name="os" value="{{ os }}" class="ui_input_txt03" /> 状态 <select id="status" name="status" class="ui_select02"> <option value=100 selected = "selected">所有</option> <option value=0 {% if status == 0 %} selected = "selected" {% endif %}>在线</option> <option value=1 {% if status == 1 %} selected = "selected" {% endif %}>已下线</option> <option value=2 {% if status == 2 %} selected = "selected" {% endif %}>未知</option> <option value=3 {% if status == 3 %} selected = "selected" {% endif %}>故障</option> <option value=4 {% if status == 4 %} selected = "selected" {% endif %}>备用</option> </select> </div> <div id="box_bottom"> <div class="pagination"> <span class="current"> {% if serverlist.has_previous %} <a href="javascript:void(0)" onclick="search_server({{ serverlist.previous_page_number }});">上一页</a> {% endif %} <span class="current"> Page {{ serverlist.number }} of {{ serverlist.paginator.num_pages }}. </span> {% if serverlist.has_next %} <a href="javascript:void(0)" onclick="search_server({{ serverlist.next_page_number }});">下一页</a> {% endif %} </span> </div> <input type="button" value="查询" class="ui_input_btn01" onclick="search_server(1);"/> <input type="button" value="新增" class="ui_input_btn01" onclick="add_server();" /> <input type="button" value="删除" class="ui_input_btn01" onclick="batdel_server();" /> <input type="button" value="导出EXCEL" class="ui_input_btn01" onclick="excel_server();" /> </div> </form> </div> </div> {% endblock %} {% block content %} <div class="ui_content"> <div class="ui_tb"> <table class="table" cellspacing="0" cellpadding="0" width="100%" align="center" border="0"> <tr> <th width="30"><input type="checkbox" id="id" name="id" /> </th> <th>主机名字</th> <th>制造商/型号</th> <th>IP</th> <th>操作系统</th> <th>CPU</th> <th>内存</th> <th>硬盘</th> <th>状态</th> <th>机房</th> <th>操作</th> </tr> {% for s in serverlist.object_list %} <tr> <td><input type="checkbox" name="idcheck" value={{ s.id }} class="acb" /></td> <td>{{ s.hostname }}</td> <td>{{ s.model }}</td> <td>{{ s.ip }}</td> <td>{{ s.os }}</td> <td>{{ s.cpu }}</td> <td>{{ s.memory }}</td> <td>{{ s.disk }}</td> <td>{% if s.status == 0 %} 在线 {% elif s.status == 1 %} 已下线 {% elif s.status == 2 %} 未知 {% elif s.status == 3 %} 故障 {% elif s.status == 4 %} 备用 {% endif %} </td> <td>{{ s.machinaroom.name }}</td> <td> <a href="javascript:void(0)" onclick="edit_server('{{ s.id }}')" class="edit">编辑</a> <a href="javascript:void(0)" onclick="del_server({{ s.id }},{{ serverlist.number }});">删除</a> </td> </tr> {% endfor %} </table> </div> </div> </div> <script type="text/javascript"> function search_server(page){ var mname = document.getElementById("mname").value; var sname = document.getElementById("sname").value; var ip= document.getElementById("ip").value; var os= document.getElementById("os").value; var status = document.getElementById("status").value; var myurl="search_server.html"+"?"+"mname="+mname+"&&sname="+sname+"&&ip="+ip+"&&os="+os+"&&status="+status+"&&page="+page; window.location.assign(encodeURI(myurl)) } function add_server(){ var width = 400; var height = 500; var left = parseInt((screen.availWidth/2) - (width/2));//屏幕居中 var top = parseInt((screen.availHeight/2) - (height/2)); var windowFeatures = "width=" + width + ",height=" + height + ",status,resizable,left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top; newWindow = window.open("add_server.html", "subWind", windowFeatures); } function edit_server(id){ var width = 400; var height = 500; var left = parseInt((screen.availWidth/2) - (width/2));//屏幕居中 var top = parseInt((screen.availHeight/2) - (height/2)); var windowFeatures = "width=" + width + ",height=" + height + ",status,resizable,left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top; newWindow = window.open("edit_server.html?id="+id, "subWind", windowFeatures); } function del_server(id,page){ if(window.confirm('确定要删除该记录吗?')){ var text1= document.getElementById("mname").value; var sname=document.getElementById("sname").value; var ip=document.getElementById("ip").value; var os=document.getElementById("os").value; var status=document.getElementById("status").value; var myurl="del_server.html"+"?"+"id="+id+"&&mname="+text1+"&&page="+page+"&&ip="+ip+"&&os="+os+"&&status="+status+"&&sname="+sname; window.location.assign(encodeURI(myurl)) return true; }else{ //alert("取消"); return false; } } function batdel_server(){ if(window.confirm('确定要删除记录吗?')){ obj = document.getElementsByName("idcheck"); var text1= document.getElementById("mname").value; var sname=document.getElementById("sname").value; var ip=document.getElementById("ip").value; var os=document.getElementById("os").value; var status=document.getElementById("status").value; check_val = []; for(k in obj){ if(obj[k].checked) check_val.push(obj[k].value); } var myurl="batdel_server.html"+"?"+"ids="+check_val+"&&mname="+text1+"&&ip="+ip+"&&os="+os+"&&status="+status+"&&sname="+sname; window.location.assign(encodeURI(myurl)) return true; }else{ return false; } } function excel_server(){ var text1 = document.getElementById("mname").value; var sname=document.getElementById("sname").value; var ip=document.getElementById("ip").value; var os=document.getElementById("os").value; var status=document.getElementById("status").value; var myurl="excel_server.html"+"?mname="+text1+"&&ip="+ip+"&&os="+os+"&&status="+status+"&&sname="+sname; window.location.assign(encodeURI(myurl)) } </script> {% endblock %} cmdbapp/serverviews.py -- coding: utf-8 -- from future import unicode_literals from django.shortcuts import render,render_to_response from django.core.paginator import Paginator,InvalidPage,EmptyPage from cmdbapp.models import * from django.http import HttpResponse from django.http import HttpResponseRedirect from xlwt import * import StringIO def search_server(request): error = False each_page = 8 mname=request.GET.get('mname','').strip() sname=request.GET.get('sname','').strip() ip=request.GET.get('ip','').strip() os=request.GET.get('os','').strip() status=int(request.GET.get('status',100)) if mname=='' and sname=='' and ip=='' and os=='' and status==100: record_list = Server.objects.all() paginator = Paginator(record_list,each_page) try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 try: contacts = paginator.page(page) except (EmptyPage, InvalidPage): contacts = paginator.page(paginator.num_pages) return render_to_response('search_server.html',{'serverlist':contacts,"mname":mname,"sname":sname,"ip":ip,"os":os,"status":status}) else: q={} if mname!='' and sname=='' and ip=='' and os=='' and status==100: a=Machinaroom.objects.filter(name__icontains=mname).values("id") q['machinaroom__in']=a if sname!='': q['hostname__icontains']=sname if ip!='': q['ip__icontains']=ip if os!='': q['os__icontains']=os if status!=100: q['status']=status record_list = Server.objects.filter(**q) paginator = Paginator(record_list,each_page) try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 try: contacts = paginator.page(page) except (EmptyPage, InvalidPage): contacts = paginator.page(paginator.num_pages) return render_to_response('search_server.html',{'serverlist':contacts,"mname":mname,"sname":sname,"ip":ip,"os":os,"status":status}) def add_server(request): if request.method=='GET': objs=Machinaroom.objects.all() return render_to_response("add_server.html",{"machinaroomlist":objs}) else: hostname=request.POST.get("serverhostname","") model=request.POST.get("servermodel","") ip=request.POST.get("serverip","") os=request.POST.get("serveros","") cpu=request.POST.get("servercpu","") memory=request.POST.get("servermemory","") disk=request.POST.get("serverdisk","") status=request.POST.get("serverstatus",0) machinaroomid=request.POST.get("servermachinaroom") machinaroom=Machinaroom.objects.get(id=int(machinaroomid)) uu=Server(hostname=hostname,model=model,ip=ip,os=os,cpu=cpu,memory=memory,disk=disk,status=status,machinaroom=machinaroom) uu.save() return HttpResponseRedirect("add_server.html") def edit_server(request): if request.method=='GET': obj=Server.objects.get(id=int(request.GET.get('id'))) objs=Machinaroom.objects.all() return render_to_response('edit_server.html',{'server':obj,'machinaroomlist':objs}) else: id=request.POST.get("id") hostname=request.POST.get("serverhostname","") model=request.POST.get("servermodel","") ip=request.POST.get("serverip","") os=request.POST.get("serveros","") cpu=request.POST.get("servercpu","") memory=request.POST.get("servermemory","") disk=request.POST.get("serverdisk","") status=request.POST.get("serverstatus",0) machinaroomid=request.POST.get("servermachinaroom") machinaroom=Machinaroom.objects.get(id=int(machinaroomid)) uu=Server.objects.filter(id=id).update(hostname=hostname,model=model,ip=ip,os=os,cpu=cpu,memory=memory,disk=disk,status=status,machinaroom=machinaroom) return HttpResponseRedirect("edit_server.html?id="+id) def del_server(request): id=request.GET.get('id') iid=int(id) Server.objects.filter(id=iid).delete() mname=request.GET.get('mname','').strip() sname=request.GET.get('sname','').strip() ip=request.GET.get('ip','').strip() os=request.GET.get('os','').strip() status=request.GET.get('status',100) page=request.GET.get('page','1') return HttpResponseRedirect('search_server.html?mname='+mname+"&&page="+page+"&&sname="+sname+"&&ip="+ip+"&&os="+os+"&&status="+status) def batdel_server(request): ids=request.GET.get('ids') b=ids.split(',') arr = map(int,b) for aaa in arr: Server.objects.filter(id=aaa).delete() mname=request.GET.get('mname') sname=request.GET.get('sname','').strip() ip=request.GET.get('ip','').strip() os=request.GET.get('os','').strip() status=request.GET.get('status',100) return HttpResponseRedirect('search_server.html?mname='+mname+"&&sname="+sname+"&&ip="+ip+"&&os="+os+"&&status="+status) def excel_server(request): mname=request.GET.get('mname','').strip() sname=request.GET.get('sname','').strip() ip=request.GET.get('ip','').strip() os=request.GET.get('os','').strip() status=int(request.GET.get('status',100)) if mname=='' and sname=='' and ip=='' and os=='' and status==100: list_obj = Server.objects.all() else: q={} if mname!='' and sname=='' and ip=='' and os=='' and status==100: a=Machinaroom.objects.filter(name__icontains=mname).values("id") q['machinaroom__in']=a if sname!='': q['hostname__icontains']=sname if ip!='': q['ip__icontains']=ip if os!='': q['os__icontains']=os if status!=100: q['status']=status list_obj = Server.objects.filter(**q) if list_obj: # 创建工作薄 ws = Workbook(encoding='utf-8') w = ws.add_sheet(u"服务器清单") w.write(0, 0, "id") w.write(0, 1, u"主机名字") w.write(0, 2, u"制造商/型号") w.write(0, 3, u"IP") w.write(0, 4, u"操作系统") w.write(0,5,u"CPU") w.write(0,6,u"内存") w.write(0,7,u"硬盘") w.write(0,8,u"状态") w.write(0,9,u"机房") # 写入数据 excel_row = 1 for obj in list_obj: data_id = obj.id data_hostname = obj.hostname data_model = obj.model data_ip = obj.ip data_os = obj.os data_cpu=obj.cpu data_memory=obj.memory data_disk=obj.disk if obj.status == 0: data_status='在线' elif obj.status == 1: data_status='已下线' elif obj.status == 2: data_status='未知' elif obj.status == 3: data_status='故障' else: data_status='备用' data_machinaroom=obj.machinaroom.name w.write(excel_row, 0, data_id) w.write(excel_row, 1, data_hostname) w.write(excel_row, 2, data_model) w.write(excel_row, 3, data_ip) w.write(excel_row, 4, data_os) w.write(excel_row, 5, data_cpu) w.write(excel_row, 6, data_memory) w.write(excel_row, 7, data_disk) w.write(excel_row, 8, data_status) w.write(excel_row, 9, data_machinaroom) excel_row += 1 sio = StringIO.StringIO() ws.save(sio) sio.seek(0) response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel') response['Content-Disposition'] = 'attachment; filename=服务器清单-'+mname+sname+ip+os+'.xls' response.write(sio.getvalue()) return response

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册