PowerDesigner中NAME和COMMENT的互相转换,需要执行语句
使用说明: 在【Tools】-【Execute Commands】-【Edit/Run Script】 下。输入下面你要选择的语句即可,也可以保存起来,以便下次使用,后缀为.vbs。 需要注意的问题是:运行语句时必须在Module模式下,如果是导出报表时执行会出现错误提示。 1.Name转到Comment注释字段。一般情况下只填写NAME,COMMENT可以运行语句自动生成。 将该语句保存为name2comment.vbs
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
Option Explicit ValidationMode = True InteractiveMode = im_Batch Dim mdl ' the current model ' get the current active model Set mdl = ActiveModel If (mdl Is Nothing) Then MsgBox "There is no current Model " ElseIf Not mdl.IsKindOf(PdPDM.cls_Model) Then MsgBox "The current model is not an Physical Data model. " Else ProcessFolder mdl End If ' This routine copy name into comment for each table, each column and each view ' of the current folder Private sub ProcessFolder(folder) Dim Tab 'running table for each Tab in folder.tables if not tab.isShortcut then if trim(tab.comment)="" then'如果有表的注释,则不改变它.如果没有表注释.则把name添加到注释里面. tab.comment = tab.name end if Dim col ' running column for each col in tab.columns if trim(col.comment)="" then '如果col的comment为空,则填入name,如果已有注释,则不添加;这样可以避免已有注释丢失. col.comment= col.name end if next end if next Dim view 'running view for each view in folder.Views if not view.isShortcut and trim(view.comment)="" then view.comment = view.name end if next ' go into the sub-packages Dim f ' running folder For Each f In folder.Packages if not f.IsShortcut then ProcessFolder f end if Next end sub |
2.将Comment内容保存到NAME中,comment2name.vbs 实习互换。语句为:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
Option Explicit ValidationMode = True InteractiveMode = im_Batch Dim mdl ' the current model ' get the current active model Set mdl = ActiveModel If (mdl Is Nothing) Then MsgBox "There is no current Model " ElseIf Not mdl.IsKindOf(PdPDM.cls_Model) Then MsgBox "The current model is not an Physical Data model. " Else ProcessFolder mdl End If Private sub ProcessFolder(folder) On Error Resume Next Dim Tab 'running table for each Tab in folder.tables if not tab.isShortcut then tab.name = tab.comment Dim col ' running column for each col in tab.columns if col.comment="" then else col.name= col.comment end if next end if next Dim view 'running view for each view in folder.Views if not view.isShortcut then view.name = view.comment end if next ' go into the sub-packages Dim f ' running folder For Each f In folder.Packages if not f.IsShortcut then ProcessFolder f end if Next end sub |
from:https://www.cnblogs.com/netsql/archive/2010/05/24/1742734.html
View DetailsPowerDesigner从Sqlserver中反转为带注释的字典及快捷键操作
PowerDesigner的操作经常忘记,所以把常用的功能记录下来备忘。 1、修改反转过来的字段 PowerDesigner从数据库反转的时候,默认不带注释,需要先进行修改。 输入如下脚本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 {OWNER, TABLE, S, COLUMN, DTTPCODE, LENGTH, SIZE, PREC, COMPUTE, NOTNULL, IDENTITY, DOMAIN, DEFAULT, COMMENT, ExtIdentityIncrement, ExtIdentitySeed} select u.name, o.name, c.colid, c.name, case when (s.usertype < 100) then s.name else x.name end, c.prec, c.length, c.scale, z.text , case (c.status & 8) when 8 then 'NULL' else 'NOTNULL' end, case (c.status & 128) when 128 then 'identity' else " end, case when (s.usertype < 100) then " else s.name end, v.text, CONVERT(varchar, ISNULL(p.[value], ")) AS text, case (c.status & 128) when 128 then ident_incr(u.name + '.' + o.name) else null end, case (c.status & 128) when 128 then ident_seed(u.name + '.' + o.name) else null end from dbo.sysusers u join dbo.sysobjects o on (o.uid = u.uid and o.type in ('U', 'S', 'V')) […]
View DetailsMysql 忘记root密码的完美解决方法
一、更改my.cnf配置文件 1.用命令编辑/etc/my.cnf配置文件,即:vim /etc/my.cnf 或者 vi /etc/my.cnf 2.在[mysqld]下添加skip-grant-tables,然后保存并退出 3.重启mysql服务:service mysqld restart 二、更改root用户名 1.重启以后,执行mysql命令进入mysql命令行 2.修改root用户密码 1 2 3 MySQL> UPDATE mysql.user SET Password=PASSWORD('新密码') where USER=’root'; MySQL> flush privileges; MySQL> exit 3.把/etc/my.cnf中的skip-grant-tables注释掉,然后重启mysql,即:service mysqld restart 好了,下面就可以用root新的密码登录了! 以上所述是小编给大家介绍的Mysql 忘记root密码处理办法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持! from:https://www.jb51.net/article/100925.htm
View Details代码规范审查 -Sonar环境搭建
Sonar概述 Sonar 是一个用于代码质量管理的开放平台,可以进行代码质量的持续跟踪审查,支持的语言包含C#、java、PHP、C等。可以通过UI一睹Sonar的强大之处。 Sonar安装 Sonar是一个基于java的开源平台,环境安装包含JDK安装、数据库安装、Sonar Server安装、Sonar Runner安装。 一、JDK安装 下载java SDK ,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 安装java sdk,直接双击exe进行运行 验证java安装是否成功,打开命令行,运行java –version, 如果显示如下图,代表安装成功! 二、数据库安装 Sonar支持数据库类型:Sql server、MySQL、Oracle,此处以MySql为例 Mysql数据库下载地址:https://www.mysql.com/downloads/, 具体安装步骤省略可自行学习。 配置Sonar数据库(创建Sonar数据库、用户等) CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE USER 'sonar' IDENTIFIED BY 'sonar'; GRANT ALL ON sonar.* TO 'sonar’@’%' IDENTIFIED BY 'sonar'; GRANT ALL ON sonar.* TO 'sonar’@’localhost' IDENTIFIED BY 'sonar'; FLUSH PRIVILEGES; 三、Sonar server及scanner配置 下载sonar(只需下载解压,无需安装) 下载地址:https://www.sonarqube.org/downloads/ 下载sonar scanner(只需下载解压,无需安装) 下载地址:https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner 添加snoar和snoar scanner到环境变量 添加SONAR_HOME、SONAR_RUNNER_HOME环境变量,并将SONAR_RUNNER_HOME加入PATH环境变量参考如下: SONAR_HOME:C:\sonar\sonarqube-6.2 SONAR_RUNNER_HOME:C:\sonar\Sonar-scanner-2.8 PATH:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;%SONAR_RUNNER_HOME%/bin;%MAVEN_HOME%\bin; 编辑sonar配置文件,修改如下: 编辑sonar\sonarqube-6.2\conf\sonar.properties文件,配置数据库设置,默认已经提供各类数据库的支持,这里使用mysql,因此取消mysql模块的注释,修改内容如下: 编辑SonarRunner配置文件,修改如下: 编辑Sonar-scanner-2.8\conf\conf\sonar-runner.properties文件,配置数据库设置,默认已经提供各类数据库的支持,这里使用mysql,因此取消mysql模块的注释,修改内容如下: 启动sonarQube服务,从sonarqube-6.2\bin\windows-x86-64目录下双击启动StartSonar.bat,启动成功显示如下: 访问http:\localhost:9000检测是否启动成功 安装中文包 […]
View DetailsWin10自带的虚拟机Hyper-V安装Centos7
1、设置开启Hyper-V应用程序 在搜索功能里输入 Hyper-V 然后点击选中的部分 2、全部选中框中的部分,然后重新启动电脑 3、在搜索功能里输入Hyper-V 打开 4、点击新建--> 下一步--> 5、修改名称 和虚拟机存储位置 6、这里一定要选择“第一代”,不然无法正常启动到安装界面 7、分配内存根据自己情况来设置 8、网络配置(网络设置的 专用虚拟机交换机为无线网卡 设置 见下图 步骤:) 专用虚拟机交换机为无线网卡 设置 步骤 9、连接虚拟硬盘 10、安装选项 选中镜像位置 11、设置信息如下:通过摘要查看 (最后点击完成后自动创建虚拟机) 12、选择创建好的虚拟机 先启动-->连接 13、安装Centos7 选中图中部分 进入安装界面 14、选择语言 最后选择英文哦 15、点击 Done 选择自动分区 16、开始安装 : 1. 设置root密码 2.创建用户 17、root密码设置 18、等待重启 然后用root用户登陆 密码是刚才设置的 18、网络配置设置 修改配置文件 网络桥接右键 桥接(桥接完成之后记得通过属性修改网桥的IP地址 手动设置) from:https://blog.csdn.net/xuanalex/article/details/79943206
View Detailslaravel 查询构建器(连贯操作)
注:laravel 查询返回行的都是 php 的 stdClass 对象实例,不是数组!!!! 1)查询多行(get)
|
1 |
DB::table('table_name')->get(); |
带偏移和限制的查询(skip take 或 offset limit)(两种用法是一样的)
|
1 2 3 4 5 |
//skip take DB::table('table_name')->skip(10)->take(10)->get(); //offset limit DB::table('table_name')->offset(20)->limit(10)->get(); |
2)查询一行(first)
|
1 |
DB::table('table_name')->first(); |
|
1 |
DB::table('table_name')->find(1); |
PS:find方法也可以查多行,它可以这样玩 DB::table('table_name')->find([1,2,3,4]); 3)直接查询一个字段(value)
|
1 |
DB::table('table_name')->where('name','Tiac')->value('email'); |
4)查询一列(pluck)
|
1 |
DB::table('table_name')->where('brand_id','100')->pluck('goods_id'); |
5)块组结果集(chunk) 使用情景: 假设我们需要查询 1 百万的数据,并对其做处理,一次性查询 1 百万并统一处理势必会对数据产生不小的压力,消耗大量的服务器资源,有没有一种更做优的处理方法? 将 1 百万的查询分成 1000 次 1000 条记录的查询的块查询怎样?? 这个 chunk的作用,chunk方法接口一个闭包函数做回调处理
|
1 2 3 4 5 |
DB::table('users')->orderBy('id')->chunk(1000, function($users) { foreach ($users as $user) { // } }); |
PS:上面只是举例,chunk 貌似不能和 limit 一起用,chunk 默认情况下一次性处理整张表的数据,不过我可以通过自己加判断用 return false 跳出 chunk 操作 6)聚合函数(count max min avg sum 等等)
|
1 |
DB::table('table_name')->count(); |
PS:其他聚合函数的使用方法一样的,不一一举例了 7)where 条件字句 这个比较多,懒得写了,想看的直接到 laravel 学院看吧,传送门:http://laravelacademy.org/post/6140.html#ipt_kb_toc_6140_8 (where, orWhere, whereNUll, whereIn, whereNotIn, whereBetween, whereNotBetween, whereDate, whereYear, whereMonth, whereDay 等等) 8)orderBy 排序字句
|
1 |
DB::table('table_name')->orderBy('id','desc')->get(); |
PS:如果想要返回随机的查询结果集,可以使用 inRandomOrder 子句 […]
View Detailslaravel5.0 groupBy中count的写法
|
1 2 3 4 |
$user_info = DB::table('usermetas') ->select('browser', DB::raw('count(*) as total')) ->groupBy('browser') ->get(); |
from:https://stackoverflow.com/questions/18533080/laravel-eloquent-groupby-and-also-return-count-of-each-group
View DetailsPHP获取IP及地区信息(纯真IP数据库)
昨天在写程序的时候,发现在用户的时候记录IP和地区信息也许以后用得上,去网上找了找,发现实现的方式有好多好多,因为我用的ThinkPHP,后来又去TP官网找了找,最后采用了下面这种方法。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
<?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2009 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: liu21st <liu21st@gmail.com> // +---------------------------------------------------------------------- /** * IP 地理位置查询类 修改自 CoolCode.CN * 由于使用UTF8编码 如果使用纯真IP地址库的话 需要对返回结果进行编码转换 * @author liu21st <liu21st@gmail.com> */ class IpLocation { /** * QQWry.Dat文件指针 * * @var resource */ private $fp; /** * 第一条IP记录的偏移地址 * * @var int */ private $firstip; /** * 最后一条IP记录的偏移地址 * * @var int */ private $lastip; /** * IP记录的总条数(不包含版本信息记录) * * @var int */ private $totalip; /** * 构造函数,打开 QQWry.Dat 文件并初始化类中的信息 * * @param string $filename * @return IpLocation */ public function __construct($filename = "UTFWry.dat") { $this->fp = 0; if (($this->fp = fopen(dirname(__FILE__).'/'.$filename, 'rb')) !== false) { $this->firstip = $this->getlong(); $this->lastip = $this->getlong(); $this->totalip = ($this->lastip - $this->firstip) / 7; } } /** * 返回读取的长整型数 * * @access private * @return int */ private function getlong() { //将读取的little-endian编码的4个字节转化为长整型数 $result = unpack('Vlong', fread($this->fp, 4)); return $result['long']; } /** * 返回读取的3个字节的长整型数 * * @access private * @return int */ private function getlong3() { //将读取的little-endian编码的3个字节转化为长整型数 $result = unpack('Vlong', fread($this->fp, 3).chr(0)); return $result['long']; } /** * 返回压缩后可进行比较的IP地址 * * @access private * @param string $ip * @return string */ private function packip($ip) { // 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False, // 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串 return pack('N', intval(ip2long($ip))); } /** * 返回读取的字符串 * * @access private * @param string $data * @return string */ private function getstring($data = "") { $char = fread($this->fp, 1); while (ord($char) > 0) { // 字符串按照C格式保存,以\0结束 $data .= $char; // 将读取的字符连接到给定字符串之后 $char = fread($this->fp, 1); } return $data; // return iconv('gb2312', 'utf-8', $data); //通用函数,不能在这转 } /** * 返回地区信息 * * @access private * @return string */ private function getarea() { $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { case 0: // 没有区域信息 $area = ""; break; case 1: case 2: // 标志字节为1或2,表示区域信息被重定向 fseek($this->fp, $this->getlong3()); $area = $this->getstring(); break; default: // 否则,表示区域信息没有被重定向 $area = $this->getstring($byte); break; } return $area; // return iconv('gb2312', 'utf-8', $area); //在最后统一转 } /** * 根据所给 IP 地址或域名返回所在地区信息 * * @access public * @param string $ip * @return array */ public function getlocation($ip='') { if (!$this->fp) return null; // 如果数据文件没有被正确打开,则直接返回空 if(empty($ip)) $ip = get_client_ip(); $location['ip'] = gethostbyname($ip); // 将输入的域名转化为IP地址 $ip = $this->packip($location['ip']); // 将输入的IP地址转化为可比较的IP地址 // 不合法的IP地址会被转化为255.255.255.255 // 对分搜索 $l = 0; // 搜索的下边界 $u = $this->totalip; // 搜索的上边界 $findip = $this->lastip; // 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息) while ($l <= $u) { // 当上边界小于下边界时,查找失败 $i = floor(($l + $u) / 2); // 计算近似中间记录 fseek($this->fp, $this->firstip + $i * 7); $beginip = strrev(fread($this->fp, 4)); // 获取中间记录的开始IP地址 // strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式 // 以便用于比较,后面相同。 if ($ip < $beginip) { // 用户的IP小于中间记录的开始IP地址时 $u = $i - 1; // 将搜索的上边界修改为中间记录减一 } else { fseek($this->fp, $this->getlong3()); $endip = strrev(fread($this->fp, 4)); // 获取中间记录的结束IP地址 if ($ip > $endip) { // 用户的IP大于中间记录的结束IP地址时 $l = $i + 1; // 将搜索的下边界修改为中间记录加一 } else { // 用户的IP在中间记录的IP范围内时 $findip = $this->firstip + $i * 7; break; // 则表示找到结果,退出循环 } } } //获取查找到的IP地理位置信息 fseek($this->fp, $findip); $location['beginip'] = long2ip($this->getlong()); // 用户IP所在范围的开始地址 $offset = $this->getlong3(); fseek($this->fp, $offset); $location['endip'] = long2ip($this->getlong()); // 用户IP所在范围的结束地址 $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { case 1: // 标志字节为1,表示国家和区域信息都被同时重定向 $countryOffset = $this->getlong3(); // 重定向地址 fseek($this->fp, $countryOffset); $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { case 2: // 标志字节为2,表示国家信息又被重定向 fseek($this->fp, $this->getlong3()); $location['country'] = $this->getstring(); fseek($this->fp, $countryOffset + 4); $location['area'] = $this->getarea(); break; default: // 否则,表示国家信息没有被重定向 $location['country'] = $this->getstring($byte); $location['area'] = $this->getarea(); break; } break; case 2: // 标志字节为2,表示国家信息被重定向 fseek($this->fp, $this->getlong3()); $location['country'] = $this->getstring(); fseek($this->fp, $offset + 8); $location['area'] = $this->getarea(); break; default: // 否则,表示国家信息没有被重定向 $location['country'] = $this->getstring($byte); $location['area'] = $this->getarea(); break; } if (trim($location['country']) == 'CZ88.NET') { // CZ88.NET表示没有有效信息 $location['country'] = '未知'; } if (trim($location['area']) == 'CZ88.NET') { $location['area'] = ''; } $location['country']=iconv('gb2312', 'utf-8', $location['country']); $location['area']=iconv('gb2312', 'utf-8', $location['area']); return $location; } /** * 析构函数,用于在页面执行结束后自动关闭打开的文件。 * */ public function __destruct() { if ($this->fp) { fclose($this->fp); } $this->fp = 0; } } IpLocation.class.php |
这个是TP里带的,从上面的信息上来看已经很旧了,不过感觉写的还不错,就没改什么,只是在后面加上了
|
1 2 |
$location['country']=iconv('gb2312', 'utf-8', $location['country']); $location['area']=iconv('gb2312', 'utf-8', $location['area']); |
因为TP的纯真数据库已经转码了,但是很旧,似乎还是2012年的,IP这东西,那么老的东西估计很不准,于是我去纯真官网下了一个,但是纯真本身是GB2312的,所以要加上上面这两句转码一下。 然后在项目中导入了这个PHP类以后,这样去用就可以。
|
1 2 3 |
$ip=get_client_ip(); $ipData=new IpLocation("QQWry20140125.dat"); $ipInfo=$ipData->getlocation($ip); |
得到的结果是这样的,测试IP:218.197.147.154。
|
1 2 3 4 5 6 |
array (size=5) 'ip' => string '218.197.147.154' (length=15) 'beginip' => string '218.197.146.1' (length=13) 'endip' => string '218.197.147.154' (length=15) 'country' => string '湖北省武汉大学' (length=21) 'area' => string '外语自主学习中心' (length=24) |
最新版的纯真数据库去纯真官网下就可以,里面的QQWry.dat就是,用的时候也可以像我那样在后面标上版本,免得以后记不清。然后把.dat跟上面的php类放在一个目录下就OK啦。 from:https://www.cnblogs.com/fordawn/p/3538665.html
View Details7 个支持敏捷的开源项目管理工具,更好地管理项目
在一项调查中,有 71% 的组织表示他们在开发过程中会用到敏捷方法。 此外,用敏捷方法管理项目比传统方法管理项目成功率高 28%。 在这次工具推荐中,我们从一些比较受欢迎的开源项目管理工具中摘取了支持敏捷的几项。 无论您的组织已经在使用敏捷,还是正计划使用,相信这 7 个开源的项目管理工具都能给你带来帮助。 1、MyCollab MyCollab 是一个高性能、稳定而且安全的商业平台,用于 CRM 客户关系管理、项目和文档管理。是一个企业的协作平台,基于 Java 开发。该系统提供开源的社区版本。 2、Odoo Odoo 的前身是 OpenERP,是一个开源的企业 ERP 系统。Odoo 不仅仅是项目管理软件, 它还是一个完整的集成商业应用套件,包括会计,人力资源,网站和电子商务,库存,制造,销售管理(CRM)等。 3、OpenProject OpenProject 是一个开源的、基于Web的项目管理应用程序。OpenProject 为项目团队提供了整个项目生命周期的支持,通过插件,OpenProject 支持: 协同项目计划 进度报告 任务管理 时间和成本报告 Scrum 等 4、OrangeScrum orangescrum 是一个采用 CakePHP 框架的 web 应用程序,可用来灵活地管理项目。OrangeScrum 支持敏捷方法,特别是使用 Scrum 任务板和看板式工作流视图。 它适用于小型组织 – 自由职业者,代理机构和中小型企业。 5、]project-open[ ]project-open[ 采用 TCL 开发的基于 Web 的项目管理系统,它能帮助你的业务涵盖领域,如客户关系管理,销售,项目规划,项目跟踪,协作,时间表,发票和付款等。 6、Taiga Taiga 是一个免费开源,而且功能非常强大的项目管理平台,用于初创企业和敏捷开发团队。提供一个简单、漂亮的项目管理工具。Taiga 采用 Python Django 框架开发,前端基于 AngularJS 实现。 7、Tuleap Tuleap Open ALM 不仅仅是一个项目管理工具,它还是一个应用生命周期管理工具,包括敏捷开发和项目管理支持。2013年 Tuleap 获得了 InforWorld.com 的 Bossie 奖,并且被财富500强公司、中小型企业和开源项目广泛使用。 Tuleap 可以灵活,传统混合,或自定义项目管理流程。支持计划,短跑,任务,报告等。这一工具非常适合开源开发公司,因为该工具还集成使用了 Git,SVN, Jenkins 等。 from:https://www.oschina.net/news/97343/agile-project-management-tools
View Details聊聊云计算:5分钟弄清楚我们为什么需要容器
除了云主机,不少应用也部署在容器里面。容器云服务也是现在云服务商的主要业务,阿里云、腾讯云等都会提供相应的容器服务。那么,我们为什么需要容器呢? 我们经常会遇到这样的问题: 1 程序在我这儿跑得好好的,怎么到你那里就不行了? 2 系统好卡,是哪个进程把CPU给吃光了? 3 这套系统我已经搭建好了,要不你再重新搭建一遍? 相信这些问题,大家平常都会遇到。容器技术是帮助我们解决这些问题的好办法。那么容器究竟是什么呢? 容器技术是这些问题的最佳解决方案 容器也是一种虚拟化技术,与虚拟机不同之处在于,虚拟机是硬件虚拟化(Hypervisor的作用),容器是对操作系统虚拟化。 虚拟机本身是不带有操作系统的,在虚拟机上部署应用时,还需要安装操作系统(一般是通过虚拟机镜像)以及其他需要的执行环境,如Tomcat等。 容器把应用以及应用的执行环境打包在一起。部署应用的时候,直接整个容器进行部署。因为容器自带应用执行环境,所以就不存在部署过程中由于环境变化,导致应用出现部署异常,可以说是“一次构建,到处执行”。 虚拟机 VS 容器 从头在虚拟机或物理机上搭建一遍环境,包括安装程序以及配置脚本,往往是非常麻烦的事情。相比于虚拟机(云主机),利用(云)容器来部署应用要更方便。 总结起来,容器有三大特点: 容器内部的东西是不可变的 相比虚拟机更轻量级,可以实现秒级启动,容器可以运行在物理机上,也可以在虚拟机上。 创建速度快,不需要复杂的环境配置 目前最常用的容器就是就是Docker,以至于大家一谈到容器,一般默认就认为是Docker。那么Docker技术与容器有什么关系呢? Docker究竟是什么? 容器技术其实已经出现十多年了,Linux2.6版本就已经支持LXC。而Docker技术的最早0.1版本直到2013年才出现,现在已经成为云计算领域一个非常常用的技术了。 Docker是以容器技术为核心的一套应用构建、部署和执行的技术体系。其中包括了Docker Daemon守护进程、Docker Container容器、Docker Client客户端以及Docker Image镜像等。 Docker守护进程本身就是一个普通的应用进程,不过是用来操作Docker镜像文件的。Docker守护进程与镜像文件一起就组成了Docker容器。 Docker容器、守护进程与镜像的关系 那这个Docker镜像文件(Docker File)里面有什么呢?Docker镜像和虚拟机快照(镜像文件)类似,分不同的层级,比如有基础镜像,仅仅包含操作系统,比如CentOS镜像;有中间件镜像,比如redis数据库镜像;还有应用镜像,就是指含有具体的应用服务的镜像了。 Docker如何部署应用 当我们需要部署应用的时候,可以从镜像中创建容器,这如同从快照中创建虚拟机,不过更轻量,启动更快,秒启。 应用是在容器中运行的。比如我们要通过容器部署一个应用: 首先下载了一个Ubuntu的镜像; 然后又安装mysql和Django应用及其依赖,来完成对它Ubutun镜像的修改; 最后通过这个镜像生成一个容器; 容器启动之后就会运行Django服务了。 容器不是完全封闭的,也需要对外提供服务,所以Docker允许公开容器的特定端口。 在启动Docker的时候,我们就可以将容器的特定端口映射到宿主机上面的任意一个端口。如果一个宿主机(虚拟机或物理机)上面要部署多个Docker容器,而且几个服务都需要80端口,那么容器的对外端口都是80,但是映射到宿主机上面就可以是任意端口,不会产生冲突。 基于Docker仓库的工作流程 Docker仓库(Registry)是用来存放Docker镜像的地方。仓库存在公有和私有之分,公有仓库docker hub提供了非常多的镜像文件,这些镜像直接拉取下来就可以运行了。 我们也可以上传自己的镜像到docker hub上,同时也可以自己搭建私有仓库用于团队项目管理。 基于Docker仓库的开发运维工作流程 基于Docker仓库,整个开发团队的DevOp工作流程大致是这样的: 开发人员构建镜像并将镜像提交到Docker仓库; 测试人员从Docker仓库拷贝镜像到测试环境进行测试; 运维人员从Docker仓库拷贝镜像部署到生产环境,通过镜像开启容器并对外提供服务 from:http://baijiahao.baidu.com/s?id=1588183340989045106&wfr=spider&for=pc
View Details