首页 文章 精选 留言 我的

精选列表

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

[译]RabbitMQ教程C#版 - 发布订阅

先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672)。如果你使用不同的主机、端口或证书,则需要调整连接设置。 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以通过邮件列表 联系我们。 发布/订阅 (使用.NET Client) 在 教程[2] 中,我们创建了一个工作队列,假设在工作队列中的每一个任务都只被分发给一个Worker。那么在这一章节,我们要做与之完全不同的事,那就是我们将要把一条消息分发给多个消费者。这种模式被称为“发布/订阅”。 为了说明、体现这种模式,我们将会建一个简单的日志系统。它将会包含两个程序 - 第一个用来发送日志消息,第二个用来接收并打印它们。 在我们建立的日志系统中,每个接收程序的运行副本都会收到消息。这样我们就可以运行一个接收程序接收消息并将日志写入磁盘;同时运行另外一个接收程序接收消息并将日志打印到屏幕上。 实质上,发布的日志消息将会被广播给所有的接收者。 交换器 在教程的前几部分,我们是发送消息到队列并从队列中接收消息。现在是时候介绍Rabbit中完整的消息传递模型了。 让我们快速回顾一下前面教程中的内容: 生产者是发送消息的用户应用程序。 队列是存储消息的缓冲区。 消费者是接收消息的用户应用程序。 在RabbitMQ中,消息传递模型的核心理念是生产者从来不会把任何消息直接发送到队列,其实,通常生产者甚至不知道消息是否会被分发到任何队列中。 然而,生产者只能把消息发送给交换器。交换器非常简单,一方面它接收来自生产者的消息,另一方面又会把接收的消息推送到队列中。交换器必须明确知道该如何处理收到的消息,应该追加到一个特定队列中?还是应该追加到多个队列中?或者应该把它丢弃?这些规则都被定义在交换器类型中。 目前交换器类型有这几种:direct,topic,headers和fanout。我们先来重点关注最后一个fanout,我们创建一个这种类型的交换器,将其命名为logs: channel.ExchangeDeclare("logs", "fanout"); fanout类型交换器非常简单,正如您可能从名字中猜出的那样,它会把收到的所有消息广播到它已知的所有队列中。这恰巧是我们的日志系统目前所需要的。 列举交换器 要列举出服务器上的交换器,您可以使用非常有用的rabbitmqctl命令行工具: sudo rabbitmqctl list_exchanges 执行上述命令后,出现的列表中将会有一些amq.*交换器和默认(未命名)交换器。这些是默认创建的,不过目前您可能用不到它们。 默认交换器 在教程的前些部分,我们对交换器这一概念还一无所知,但仍然可以把消息发送到队列。之所以这样,是因为我们使用了一个用空字符串("")标识的默认交换器。 回顾一下我们之前如何发布消息: var message = GetMessage(args); var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body); 第一个参数就是交换器的名称,空字符串表示默认或匿名交换器:将消息路由到routingKey指定的队列(如果存在)中。 现在,我们可以把消息发布到我们指定的交换器: var message = GetMessage(args); var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "logs", routingKey: "", basicProperties: null, body: body); 临时队列 您是否还记得之前我们使用过的队列,它们都有一个特定的名称(记得应该是hello和task_queue吧)。给队列命名对我们来说是至关重要的 -- 因为我们可能需要多个Worker指向同一个队列;当您想要在生产者和消费者之间共享队列时,给队列一个名称也是非常重要的。 但是,我们创建的日志系统并不希望如此。我们希望监听所有的日志消息,而不仅仅是其中一部分。我们也只对目前流动的消息感兴趣,而不是旧消息。为解决这个问题,我们需要做好两件事。 首先,我们无论何时连接Rabbit,都需要一个新的、空的队列。要做到这一点,我们可以使用随机名称来创建队列,或许,甚至更好的方案是让服务器为我们选择一个随机队列名称。 其次,一旦我们与消费者断开连接,与之相关的队列应该被自动删除。 在.NET客户端中,如果不向QueueDeclare()方法提供任何参数,实际上就是创建了一个非持久化、独占、且自动删除的随机命名队列: var queueName = channel.QueueDeclare().QueueName; 您可以在队列指南中了解更多关于exclusive参数和其他队列属性的信息。 此时,queueName包含一个随机队列名称。例如,它看起来可能像amq.gen-JzTY20BRgKO-HjmUJj0wLg。 绑定 我们已经创建好了一个fanout交换器和一个队列。现在我们需要告诉交换器把消息发送到我们的队列。而交换器和队列之间的关系就称之为绑定。 // 把一个队列绑定到指定交换器。 channel.QueueBind(queue: queueName, exchange: "logs", routingKey: ""); 从现在起,logs交换器会把消息追加到我们的队列中。 列举绑定 您可以使用(您或许已经猜到了),列举出现有的绑定。 sudo rabbitmqctl list_bindings 组合在一起 生产者程序负责分发消息,这与之前的教程看起来没有太大区别。 最重要的变化是我们现在想把消息发布到我们的logs交换器,而不是匿名交换器。在发送时我们需要提供一个路由键routingKey,但是对于fanout交换器,它的值可以被忽略。这里是EmitLog.cs文件的代码: using System; using RabbitMQ.Client; using System.Text; class EmitLog { public static void Main(string[] args) { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: "logs", type: "fanout"); var message = GetMessage(args); var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "logs", routingKey: "", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } private static string GetMessage(string[] args) { return ((args.Length > 0) ? string.Join(" ", args) : "info: Hello World!"); } } (EmitLog.cs源码) 如你所见,在建立连接后,我们声明了交换器。这一步非常有必要,因为发布消息到一个不存在的交换器,这种情况是被禁止的。 如果没有队列绑定到交换器上,消息将会丢失,但这对我们来说并没有什么没问题;如果没有消费者正在监听,我们是可以放心地把消息丢弃的。 ReceiveLogs.cs的代码: using System; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; class ReceiveLogs { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: "logs", type: "fanout"); var queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queue: queueName, exchange: "logs", routingKey: ""); Console.WriteLine(" [*] Waiting for logs."); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] {0}", message); }; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } } (ReceiveLogs.cs源码) 按照教程[1]中的设置说明生成EmitLogs和ReceiveLogs项目。 如果您想把日志保存到文件中,只需打开一个控制台并输入: cd ReceiveLogs dotnet run > logs_from_rabbit.log 如果你想在屏幕上看到日志,我可以新开一个终端并运行: cd ReceiveLogs dotnet run 当然,分发日志需要输入: cd EmitLog dotnet run 使用rabbitmqctl list_bindings命令,您可以验证代码是否真正创建了我们想要的绑定和队列。当有两个ReceiveLogs.cs程序运行时,您应该看到如下所示的内容: sudo rabbitmqctl list_bindings # => Listing bindings ... # => logs exchange amq.gen-JzTY20BRgKO-HjmUJj0wLg queue [] # => logs exchange amq.gen-vso0PVvyiRIL2WoV3i48Yg queue [] # => ...done. 对执行结果的解释简洁明了:来自logs交换器的数据转发到了两个由服务器随机分配名称的队列。这正是我们期待的结果。 想要了解如何监听消息的这一块内容,让我们继续阅读教程[4]。 写在最后 本文翻译自RabbitMQ官方教程C#版本。如本文介绍内容与官方有所出入,请以官方最新内容为准。水平有限,翻译的不好请见谅,如有翻译错误还请指正。 原文链接:RabbitMQ tutorial - Publish/Subscribe 实验环境:RabbitMQ 3.7.4 、.NET Core 2.1.3、Visual Studio Code 最后更新:2018-06-11

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

CentOS7 安装Redis 单机版

1,下载Redis4.0.9 进入Redis中文网的下载页面 http://www.redis.cn/download.html 2,上传压缩包到linux系统 cd /user/local/java rz +选择本地Redis路径上传 tar -zxvfredis-4.0.9.tar.gz wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gztar -xzvf tcl8.6.1-src.tar.gzcd /usr/local/tcl8.6.1/unix/./configuremake && make install 不安装的的话,redis在maketest是会失败 cd redis-4.0.9/ make && make test && make install 至此安装过程完毕!!! 3,测试安装情况 cd/usr/local/java/redis-4.0.9/src ./redis-server 看到上面这个界面的时候就说明redis已经成功安装了。 4,以后台进程的方式启动Redis (1)redis utils目录下,有个redis_init_script脚本(2)将redis_init_script脚本拷贝到linux的/etc/init.d目录中,将redis_init_script重命名为redis_6379,6379是我们希望这个redis实例监听的端口号(3)修改redis_6379脚本的第6行的REDISPORT,设置为相同的端口号(默认就是6379)(4)创建两个目录:/etc/redis(存放redis的配置文件),/var/redis/6379(存放redis的持久化文件)(5)修改redis配置文件(默认在根目录下,redis.conf),拷贝到/etc/redis目录中,修改名称为6379.conf(6)修改redis.conf中的部分配置为生产环境 daemonize yes 让redis以daemon进程运行pidfile /var/run/redis_6379.pid 设置redis的pid文件位置port 6379 设置redis的监听端口号dir /var/redis/6379 设置持久化文件的存储位置 (7)启动redis,执行cd /etc/init.d, chmod 777 redis_6379,./redis_6379 start (8)确认redis进程是否启动,ps -ef | grep redis (9)让redis跟随系统启动自动启动 在redis_6379脚本中,最上面,加入两行注释,注释的意思是,redis服务必须在运行级2,3,4,5下被启动或关闭,启动的优先级是90,关闭的优先级是10。 # chkconfig: 2345 90 10 # description: Redis is a persistent key-value database 最后在执行 运行 chkconfig redis_6379 on 5,redis cli的使用 redis-cli SHUTDOWN,连接本机的6379端口停止redis进程 redis-cli -h 127.0.0.1 -p 6379 SHUTDOWN,制定要连接的ip和端口号 redis-cli PING,ping redis的端口,看是否正常 redis-cli,进入交互式命令行 6,如何在window客户端访问 1,修改6379.config 1) 将bind 127.0.0.1 注释掉2) 将protected-mode 设置为no 2,关闭linux防火墙CentOS7关闭/开启防火墙出现 Unit iptables.service failed to load 重启redis即可开开心心编码,快快乐乐生活。

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

[译]RabbitMQ教程C#版 - "Hello World"

先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672)。如果你使用不同的主机、端口或证书,则需要调整连接设置。 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以通过邮件列表 联系我们。 介绍 RabbitMQ是一个消息中间件:它接收并转发消息。您可以把它想象为一个邮局:当您把需要寄出的邮件投递到邮箱,邮差最终会把邮件送给您的收件人。在这个比喻中,RabbitMQ就是一个邮箱,也可以理解成邮局和邮递员。 RabbitMQ和邮局的主要区别在于它不处理纸张,而是接收、存储和转发二进制数据块 - 消息。 RabbitMQ和消息传递通常使用一些术语。 生产的意思无非就是发送。发送消息的程序就是一个生产者: 队列就是RabbitMQ内部“邮箱”的名称。虽然消息流经RabbitMQ和您的应用程序,但它们只能存储在队列中。队列只受主机的内存和磁盘的限制,它本质上就是一个很大的消息缓冲区。多个生产者可以发送消息到一个队列,并且多个消费者可以尝试从一个队列接收数据。这就是我们代表队列的方式: 消费与接收有相似的含义。主要等待接收消息的程序就是一个消费者: 注意:生产者、消费者和中间件不是必须部署在同一主机上,实际上在大多数应用程序中它们不是。 "Hello World" 使用.NET / C#Client 在教程的这一部分,我们将用C#编写两个程序:一个发送单条消息的生产者,以及接收消息并将其打印出来的消费者。我们将忽略.NET客户端API中的一些细节,专注于更简单的开始。这是一个消息传递的“Hello World”。 在下图中,P是我们的生产者,C是我们的消费者。中间的盒子是队列 - RabbitMQ代表消费者保存的消息缓冲区。 .NET客户端库 RabbitMQ支持多种协议,本教程使用AMQP 0-9-1,它是一种开放的、通用的消息传递协议。RabbitMQ提供了一些针对不同 语言环境 的客户端,我们将使用RabbitMQ提供的.NET客户端。 客户端支持 .NET Core 以及.NET Framework 4.5.1+。本教程将使用.NET Core,因此您需要确保客户端已 安装 并且路径添加到PATH系统变量。 您也可以使用.NET Framework来完成本教程,但设置步骤会有所不同。 RabbitMQ .NET客户端5.0及更高版本通过 nuget发布。 本教程假定您在Windows上使用PowerShell。在MacOS和Linux上,几乎所有shell也都可以正常工作。 安装 首先让我们验证您在PATH系统变量是否有.NET Core工具链: dotnet --help 应该产生帮助信息。 现在,让我们生成两个项目,一个用于发布者,另一个用于消费者: dotnet new console --name Send mv Send/Program.cs Send/Send.cs dotnet new console --name Receive mv Receive/Program.cs Receive/Receive.cs 这将创建两个名为Send和Receive的新目录。 然后,我们添加客户端依赖项。 cd Send dotnet add package RabbitMQ.Client dotnet restore cd ../Receive dotnet add package RabbitMQ.Client dotnet restore 我们已经建立了.NET项目,现在我们可以编写一些代码。 发送 我们将调用我们的消息发布者(发送者)Send.cs和我们的消息消费者(接收者)Receive.cs。发布者将连接到RabbitMQ,发送一条消息,然后退出。 在 Send.cs 中,我们需要使用一些命名空间: using System; using RabbitMQ.Client; using System.Text; 设置类: class Send { public static void Main() { ... } } 然后,我们可以创建一个连接,连接到服务器: class Send { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { ... } } } } 该连接抽象了套接字连接,并为我们处理协议版本的协商和身份验证等。在这里,我们连接的是本地机器上的代理, 因此是localhost。如果我们想连接到其他机器上的代理,我们只需在此指定其名称或IP地址。 接下来,我们创建一个通道,该API的主要功能是把获得信息保存起来。 想要发送,我们必须为需要发送的消息声明一个队列,然后我们可以把消息发布到队列中: using System; using RabbitMQ.Client; using System.Text; class Send { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } 声明队列是 幂等 的 - 只有当它不存在时才会被创建。消息内容是一个字节数组,所以您可以用喜欢的任意方式编码。 当上面的代码完成运行时,通道和连接将被释放。这就是我们的发布者。 (Send.cs源码) 发送不起作用! 如果这是您第一次使用RabbitMQ,并且您没有看到“已发送”消息,那么您可能会挠着头想知道错误出在什么地方。也许是代理程序启动时没有足够的可用磁盘空间(默认情况下,它至少需要50 MB空闲空间),因此拒绝接收消息。 必要时检查代理程序日志文件来确认和减少限制。配置文件 文档 将告诉您如何设置disk_free_limit。 接收 至于消费者,它是把消息从RabbitMQ拉取过来。因此,与发布消息的发布者不同,我们会保持消费者持续不断地运行,监听消息并将其打印出来。 代码(在 Receive.cs 中)具有与Send差不多一样的using声明: using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Text; 设置与发布者相同;我们开启一个连接和一个通道,并声明我们将要使用的队列。请注意,这需要与Send发布到的队列相匹配。 class Receive { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); ... } } } } 请注意,我们在这里也声明了队列。因为我们可能会在发布者之前启动消费者,所以我们希望在我们尝试从它中消费消息之前确保队列已存在。 我们即将告诉服务器将队列中的消息传递给我们。由于它会异步推送消息,因此我们提供了一个回调。这就是EventingBasicConsumer.Received事件处理程序所做的事情。 using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Text; class Receive { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } } (Receive.cs源码) 组合在一起 打开两个终端。 运行消费者: cd Receive dotnet run 运行生产者: cd Send dotnet run 消费者将打印它通过RabbitMQ从发布者处获得的消息。消费者将继续运行、等待新消息(按Ctrl-C将其停止),可以尝试从开启另一个终端运行发布者。 接下来可以跳转到 教程[2],构建一个简单的工作队列。 写在最后 本文翻译自RabbitMQ官方教程C#版本。如本文介绍内容与官方有所出入,请以官方最新内容为准。水平有限,翻译的不好请见谅,如有翻译错误还请指正。 原文链接:RabbitMQ tutorial - "Hello World!" 实验环境:RabbitMQ 3.7.4 、.NET Core 2.1.3、Visual Studio Code 最后更新:2018-03-13

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

Base64编解码(C++版)

#include<string> usingnamespacestd; classZBase64 { public: /*编码 DataByte [in]输入的数据长度,以字节为单位 */ stringEncode(constunsignedchar*Data,intDataByte); /*解码 DataByte [in]输入的数据长度,以字节为单位 OutByte [out]输出的数据长度,以字节为单位,请不要通过返回值计算 输出数据的长度 */ stringDecode(constchar*Data,intDataByte,int&OutByte); }; #include"stdAfx.h" #include"ZBase64.h" stringZBase64::Encode(constunsignedchar*Data,intDataByte) { //编码表 constcharEncodeTable[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //返回值 stringstrEncode; unsignedcharTmp[4]={0}; intLineLength=0; for(inti=0;i<(int)(DataByte/3);i++) { Tmp[1]=*Data++; Tmp[2]=*Data++; Tmp[3]=*Data++; strEncode+=EncodeTable[Tmp[1]>>2]; strEncode+=EncodeTable[((Tmp[1]<<4)|(Tmp[2]>>4))&0x3F]; strEncode+=EncodeTable[((Tmp[2]<<2)|(Tmp[3]>>6))&0x3F]; strEncode+=EncodeTable[Tmp[3]&0x3F]; if(LineLength+=4,LineLength==76){strEncode+="\r\n";LineLength=0;} } //对剩余数据进行编码 intMod=DataByte%3; if(Mod==1) { Tmp[1]=*Data++; strEncode+=EncodeTable[(Tmp[1]&0xFC)>>2]; strEncode+=EncodeTable[((Tmp[1]&0x03)<<4)]; strEncode+="=="; } elseif(Mod==2) { Tmp[1]=*Data++; Tmp[2]=*Data++; strEncode+=EncodeTable[(Tmp[1]&0xFC)>>2]; strEncode+=EncodeTable[((Tmp[1]&0x03)<<4)|((Tmp[2]&0xF0)>>4)]; strEncode+=EncodeTable[((Tmp[2]&0x0F)<<2)]; strEncode+="="; } returnstrEncode; } stringZBase64::Decode(constchar*Data,intDataByte,int&OutByte) { //解码表 constcharDecodeTable[]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 62,//'+' 0,0,0, 63,//'/' 52,53,54,55,56,57,58,59,60,61,//'0'-'9' 0,0,0,0,0,0,0, 0,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,//'A'-'Z' 0,0,0,0,0,0, 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,//'a'-'z' }; //返回值 stringstrDecode; intnValue; inti=0; while(i<DataByte) { if(*Data!='\r'&&*Data!='\n') { nValue=DecodeTable[*Data++]<<18; nValue+=DecodeTable[*Data++]<<12; strDecode+=(nValue&0x00FF0000)>>16; OutByte++; if(*Data!='=') { nValue+=DecodeTable[*Data++]<<6; strDecode+=(nValue&0x0000FF00)>>8; OutByte++; if(*Data!='=') { nValue+=DecodeTable[*Data++]; strDecode+=nValue&0x000000FF; OutByte++; } } i+=4; } else//回车换行,跳过 { Data++; i++; } } returnstrDecode; } 使用示例(结合CxImage库): CStringCScanDlg::EncodeImage() {//对图片进行Base64编码 ZBase64zBase; //图片编码 CxImageimage;//定义一个CxImage对象 image.Load(this->m_strImgPath,CXIMAGE_FORMAT_JPG);//先装载jpg文件,需要指定文件类型 longsize=0;//得到图像大小 BYTE*buffer=0;//存储图像数据的缓冲 image.Encode(buffer,size,CXIMAGE_FORMAT_JPG);//把image对象中的图像以type类型数据copy到buffer stringstrTmpResult=zBase.Encode(buffer,size); CStringresult; result=strTmpResult.c_str(); returnresult; } voidCScanDlg::DecodeImageData(CStringstrData) {//对Base64编码过的数据解码并显示原图片 ZBase64zBase; intOutByte=0; stringstrTmpResult=zBase.Decode(strData,strData.GetLength(),OutByte); inti,len=strTmpResult.length(); BYTE*buffer=newBYTE[len]; for(i=0;i<len;++i) { buffer[i]=strTmpResult[i]; } CxImageimage(buffer,len,CXIMAGE_FORMAT_JPG);//把内存缓冲buffer中的数据构造成Image对象 delete[]buffer; CDC*hdc=m_picture.GetDC(); m_bitmap=image.MakeBitmap(hdc->m_hDC); HBITMAPh0ldBmp=m_picture.SetBitmap(m_bitmap); if(h0ldBmp)DeleteObject(h0ldBmp); if(hdc->m_hDC)m_picture.ReleaseDC(hdc); if(m_bitmap)DeleteObject(m_bitmap); } 作者:洞庭散人 出处:http://phinecos.cnblogs.com/ 本博客遵从 Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。

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

Windows Server 2012正式版RDS系列②

在上一篇中,我给大家分享了基本的快速部署“BS架构的应用程序虚拟化和多会话同服务器的远程桌面连接”,那今天我就带着大家详细看看控制台的变化和一些变化的细节或特性吧。 登陆进我们的RDS服务器,我们首先看看本地计算机组,在之前的windows server 2008 r2中,是否还记得,如果要允许远程桌面,那么我们需要在RDU组里添加允许的用户?那在ws2012(Windows Server 2012简称WS2012)中是否有变化呢? 自动安装好以后的RDU组已经添加好了普通域用户组了。但是我们需要注意下本地用户组里同时也多了4个组: 这些分别是什么用途呢? RDS Endpoint Servers:此组中的服务器运行虚拟机和主机会话,用户 RemoteApp 程序和个人虚拟桌面将在这些虚拟机和会话中运行。需要将此组填充到运行 RD 连接代理的服务器上。在部署中使用的 RD 会话主机服务器和 RD 虚拟化主机服务器需要位于此组中。 RDS Management Servers:此组中的服务器可以在运行远程桌面服务的服务器上执行例程管理操作。需要将此组填充到远程桌面服务部署中的所有服务器上。必须将运行 RDS 中心管理服务的服务器包括到此组中。 RDS Remote Access Servers:此组中的服务器使 RemoteApp 程序和个人虚拟桌面用户能够访问这些资源。在面向 Internet 的部署中,这些服务器通常部署在边缘网络中。需要将此组填充到运行 RD 连接代理的服务器上。在部署中使用的 RD 网关服务器和 RD Web 访问服务器需要位于此组中。 Remote Desktop Users:此组中的成员被授予远程登录的权限 Remote Management Users:此组的成员可以通过管理协议(例如,通过 Windows 远程管理服务实现的 WS-Management)访问 WMI 资源。这仅适用于授予用户访问权限的 WMI 命名空间。 在RDS的服务器管理中,我们还可以看到目前我们远程桌面服务的架构拓扑是怎样的: 这样非常直观,从拓扑中我们可以看到RD网关目前是没有的,RD授权也是没有的,那么我们直接点击添加就可以添加新的服务器角色进我们的拓扑并且自动完成部署!RD虚拟化主机也就是“BS架构的应用程序虚拟化和虚拟桌面”目前也是没有的。 在集合中的“任务”下拉表中我们可以“编辑部署属性”,如下图: 可以配置网关,添加授权服务器,证书等 在主机服务器的任务下拉列表中我们可以对现有环境添加更多的会话主机服务器操作。 在“快速会话集合”中我们可以对集合进行编辑,如下图: 可以做一些访问控制、客户端登陆映射控制、以及新增的功能:“用户配置文件磁盘”,这个是什么呢?以前我们做用户配置文件漫游是利用文件服务器并结合组策略,而在WS2012中这个变成了虚拟磁盘,方便迁移,管理,扩展等等,这样就更家方便管理和保护用户数据了,如下图: 管理员可以选择保存用户的那些数据,这些对于使用虚拟桌面的用户意义就很大了。 下面就是控制RemoteApp程序的地方了,可以增减APP的发布 当然我们还可以选择已经发布的某一个应用程序进行权限管理或关联管理等,如下图: 当然除了这些以外,还新增了一个功能就是在我们发布的RDWEB网页上以前是不能把这些应用分类的,现如今在WS2012中我们可以把这些应用利用文件夹显示的方式进行分类,如下图: 在这我把计算器输入个分类名称“小工具”,那么我们的RDWEB就会出现如下图的展示: 计算器就在“小工具”的文件夹里了哦 本文转自 ZJUNSEN 51CTO博客,原文链接:http://blog.51cto.com/rdsrv/983478,如需转载请自行联系原作者

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

0.11.1版本docker安装与使用

关于什么是docker,请参考http://baike.baidu.com/view/11854949.htm?fr=aladdin 我的服务器是ubuntu server 12.04,硬件是dell R420 一、安装 1、安装源 1 2 3 apt-keyadv--keyserverhkp: //keyserver .ubuntu.com:80--recv-keys36A1D7869245C8950F966E92D8576A8BA88D21E9 sh-c "echodebhttps://get.docker.io/ubuntudockermain>/etc/apt/sources.list.d/docker.list" apt-getupdate 2、安装docker 1 apt-get install lxc-docker 3、下载tar包并加入镜像里 一般下载镜像的时候,都是先docker search image_name,然后docker pullimage_name 但由于最近GFW屏蔽了网络,在现在的时候会出现以下错误,根本pull不了镜像。 1 2 Pullingrepositorycentos 2014 /05/19 13:35:11Gethttps: //cdn-registry-1 .docker.io /v1/repositories/library/centos/tags : read tcp162.159.253.251:443:connectiontimedout 所以为了解决此问题,我就从别的地方下载了打包好的tar(后边会解释然后自己打包的),然后使用docker load导入 先下载(有centos与ubuntu) 1 2 wgethttp: //docker .widuu.com /centos . tar wgethttp: //docker .widuu.com /ubuntu . tar 加入到镜像里 1 2 dockerload-icentos. tar dockerload-iubuntu. tar 查看镜像列表 1 2 3 4 5 6 root@ip-10-10-25-218:~ /docker/images #dockerload-icentos.tar root@ip-10-10-25-218:~ /docker/images #dockerload-iubuntu.tar root@ip-10-10-25-218:~ /docker/images #dockerimages REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE <none><none>607347d2a9463monthsago300.2MB ubuntu /widuu latest963b9d0e10ba3monthsago155MB 给centos的改个名 1 2 3 4 5 root@ip-10-10-25-218:~ /docker/images #dockertag607centos:latest root@ip-10-10-25-218:~ /docker/images #dockerimages REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE centoslatest607347d2a9463monthsago300.2MB ubuntu /widuu latest963b9d0e10ba3monthsago155MB 测试镜像是否可用 1 2 3 4 5 6 7 8 9 root@ip-10-10-25-218:~ /docker/images #dockerimages REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE centoslatest607347d2a9463monthsago300.2MB ubuntu /widuu latest963b9d0e10ba3monthsago155MB root@ip-10-10-25-218:~ /docker/images #dockerruncentos/bin/echo"hello,i'mcentossystem" hello,i'mcentossystem root@ip-10-10-25-218:~ /docker/images #dockerrunubuntu/widuu/bin/echo"hello,i'mubuntusystem" hello,i'mubuntusystem root@ip-10-10-25-218:~ /docker/images # 使用交换模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 bash -4.1 #root@ip-10-10-25-218:~/docker/exercise/node#dockerrun-i-tcentos/bin/bash bash -4.1 #ifconfig eth0Linkencap:EthernetHWaddrBA:08:86:7F:F8:48 inetaddr:172.17.0.6Bcast:0.0.0.0Mask:255.255.0.0 inet6addr:fe80::b808:86ff:fe7f:f848 /64Scope :Link UPBROADCASTRUNNINGMTU:1500Metric:1 RXpackets:6errors:0dropped:2overruns:0frame:0 TXpackets:2errors:0dropped:0overruns:0carrier:0 collisions:0txqueuelen:1000 RXbytes:488(488.0b)TXbytes:168(168.0b) loLinkencap:LocalLoopback inetaddr:127.0.0.1Mask:255.0.0.0 inet6addr:::1 /128 Scope:Host UPLOOPBACKRUNNINGMTU:1500Metric:1 RXpackets:0errors:0dropped:0overruns:0frame:0 TXpackets:0errors:0dropped:0overruns:0carrier:0 collisions:0txqueuelen:0 RXbytes:0(0.0b)TXbytes:0(0.0b) bash -4.1 #exit 退出有2中一种是完全退出,使用exit,另外一中是不完全退出,使用ctrl-p与ctrl-q 这样你推人退出了,但容器状态还是存在。 可用使用docker attach CONTAINER ID来重新进入 二、私有库 由于GFW,所以玩docker没办法pull与push,并且为了安全考虑,为了解决就搭建了私有库。 1 2 3 4 5 6 7 8 9 10 gitclonehttps: //github .com /dotcloud/docker-registry .git cddocker-registry cd config cpconfig_sample.ymlconfig.yml cd .. apt-getinstallpython-pipgunicornbuild-essentialpython-devlibevent-dev python-pipliblzma-dev-y pipinstall-rrequirements.txt gunicorn-kgevent--max-requests100--graceful-timeout3600-t3600-blocalhost:5000-w8-D--access-logfile /tmp/gunicorn .logdocker_registry.wsgi:application 客户端推送镜像到私有库 1、先注册账号 1 dockerloginlocalhost:5000 依次输入你的账号、密码、email 2、给提交的镜像打标签 1 2 3 4 5 6 root@ip-10-10-25-218:~ /docker/exercise/node #dockerimages REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE centos-initlatest5abf7cce37673minutesago1.034GB centoslatest607347d2a9463monthsago300.2MB ubuntu /widuu latest963b9d0e10ba3monthsago155MB root@ip-10-10-25-218:~ /docker/exercise/node #dockertag5abf7cce3767localhost:5000/centos-init 3、推送到私有库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 root@ip-10-10-25-218:~ /docker/exercise/node #dockerpushlocalhost:5000/centos-init Thepushreferstoarepository[localhost:5000 /centos-init ](len:1) Sendingimagelist Pushingrepositorylocalhost:5000 /centos-init (1tags) Image384630bcda7calreadypushed,skipping Image607347d2a946alreadypushed,skipping 5abf7cce3767:Imagesuccessfullypushed Pushingtag for rev[5abf7cce3767]on{http: //localhost :5000 /v1/repositories/centos-init/tags/latest } root@ip-10-10-25-218:~ /docker/exercise/node #dockerimages REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE centos-initlatest5abf7cce37676minutesago1.034GB localhost:5000 /centos-init latest5abf7cce37676minutesago1.034GB centoslatest607347d2a9463monthsago300.2MB ubuntu /widuu latest963b9d0e10ba3monthsago155MB 三、自制镜像 参考http://docs.docker.io/articles/baseimages/ 我是在ubuntu系统,所以使用https://github.com/dotcloud/docker/blob/master/contrib/mkimage-rinse.sh 由于使用rinse创建,所以需要安装 1 apt-get install rinse 安装centos 5系统 1 bash mkimage-rinse.shdenglei /centos centos-5 安装centos 6系统 检测 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 root@ip-10-10-25-218: /tmp #dockerimages REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE denglei /centos 6.518eb9205a9272minutesago127.2MB denglei /centos 5.102b76af55f4cc5minutesago81.08MB centos-test2latest21639e6b708aAboutanhourago356.7MB ubuntu- test latesta95d7aa1d99139hoursago161.8MB centos- test latest28870be2e71639hoursago356.7MB centos-omsalatestd3c15db5624e39hoursago1.048GB centos-initlatest58ef41091c2b11daysago1.055GB localhost:5000 /centos-init latest5abf7cce376711daysago1.034GB centoslatest607347d2a9464monthsago300.2MB ubuntu /widuu latest963b9d0e10ba4monthsago155MB root@ip-10-10-25-218: /tmp #dockerrundenglei/centos:5.10/bin/echo"hello,i'mcentos5.10system" hello,i'mcentos5.10system root@ip-10-10-25-218: /tmp #dockerrundenglei/centos:6.5/bin/echo"hello,i'mcentos6.5system" hello,i'mcentos6.5system docker里centos无法ssh的问题 需要关闭pam 1 sed -i "s/UsePAM.*/UsePAMno/g" /etc/ssh/sshd_config 重启ssh服务 1 /etc/init .d /sshd restart 同时别忘记设置密码 本文转自 reinxu 51CTO博客,原文链接:http://blog.51cto.com/dl528888/1427150,如需转载请自行联系原作者

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

Java版俄罗斯方块(附源码)

最近学习Java SE。一直想找个东西练手。 不过想来想去,还是经典的俄罗斯方块最好了。毕竟这个游戏要考虑的东西还是挺多的,综合性强。用来练练JavaSE还是挺不错的。好了,切入正题。 基本说明: 开发平台: MyEclipse 7.5 测试平台: Windows Server 2008 + Ubuntu Linux 9.04 运行界面如下: 程序使用方向键控制,向上键控制图形旋转。 这个程序采用类似于MVC的结构。以前我学过很长时间的VC++ MFC,深受其Document-View架构思想的影响。其实Document-View也是MVC的一种体现。 程序分成三个基本模块: MyController。控制器,程序的核心。 MainFrm。主窗体,实现了UI的呈现。我偷了一下懒,使用了MyEclipse的可视化swing生成器,产生了一堆很不好看的代码,不过没什么影响。 MyModel。俄罗斯方块的抽象模型。主要是一个数组。 这个程序有一个关键的地方就是图形旋转时的坐标变换,为此我特地查了一下以前的解析几何的课本(呵呵,全忘了),其公式我已经写在程序的注释里面。位于MyController类的 transformCoords()方法 如果有什么疑问可以联系我。我会详细解答。 下载地址: 已编译的程序 源码 附件:http://down.51cto.com/data/2353651 本文转自 kevx 51CTO博客,原文链接:http://blog.51cto.com/spinlock/189793,如需转载请自行联系原作者

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

应用程序架构指导袖珍版

微软模式与实践小组最近发布了应用程序架构指导袖珍版本,总共有6本,分别介绍了不同类型应用程序的架构指导,包括敏捷架构方法、Mobile应用程序、RIA应用程序、富客户端应用程序、Web应用程序以及Service架构等,非常值得一看。 1. 敏捷架构方法 下载指导 2. Web引用架构 下载指导 3. 移动应用架构 下载指导 4. RIA架构 下载指导 5. 富客户端架构 下载指导 6. 服务架构 下载指导 本文转自lihuijun51CTO博客,原文链接:http://blog.51cto.com/terrylee/151994 ,如需转载请自行联系原作者

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

简化 Openstack Havana 版 compute 节点部署程序

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 #!/usr/bin/envpython #-*-coding:UTF-8-*- "" " @Item:InstallOpenstackCompute @Author:william @Group:NetworkSystemGroup @Date:2014-03-20 @Funtion: Function:DepolyOpenstackCompute... "" " import os,sys, time import traceback,shutil import commands import re defLOG(info): logfile= '/tmp/openstack_compute_install.log' files= open (logfile, 'a' ) try: files.write( '%s:%s' %( time .ctime(),info)) exceptIOError: files.close() files.close() classDepolyCompute(object): def__init__(self): print "PleasewriteinthescriptmasterIPpublicIPandlocalmanagement...\n" self.masterIPaddr= '192.168.220.1' self.localIPaddr= '192.168.220.1' self.URL= 'http://%s/source/' %self.masterIPaddr self.nova_path= '/etc/nova/' definstall_packstack(self): yum_path= '/etc/yum.repos.d/' #epel源目前不在更新OpenStackHavana版本,在下载源的时候默认已经移植了目录结构,需要重新安装RDO,在修改源路径,才能正常安装OpenStack等 comds= "https://repos.fedorapeople.org/repos/openstack/EOL/openstack-havana/rdo-release-havana-9.noarch.rpm" commands.getstatusoutput(cmd) try: cmd= "https://repos.fedorapeople.org/repos/openstack/EOL/openstack-havana/rdooo-release-havana-9.noarch.rpm" x,y=commands.getstatusoutput(cmd) if x!=0: fp= open ( '%s/rdo-release.repo' %yum_path, 'w' ) fp.write( "" "[openstack-havana]\n" "" ) fp.write( "" "name=OpenStackHavanaRepository\n" "" ) fp.write( "" "baseurl=https://repos.fedorapeople.org/repos/openstack/EOL/openstack-havana/epel-6/\n" "" ) fp.write( "" "enabled=1\n" "" ) fp.write( "" "skip_if_unavailable=0\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-RDO-Havana\n" "" ) fp.write( "" "priority=98\n" "" ) fp.close() cmd= "rpm-Uvhhttp://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm" x,y=commands.getstatusoutput(cmd) if x!=0: fp= open ( '%s/epel.repo' %yum_path, 'w' ) fp.write( "" "[epel]\n" "" ) fp.write( "" "name=ExtraPackagesforEnterpriseLinux6-$basearch\n" "" ) fp.write( "" "#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch\n" "" ) fp.write( "" "mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch\n" "" ) fp.write( "" "failovermethod=priority\n" "" ) fp.write( "" "enabled=1\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6\n" "" ) fp.write( "" "\n" "" ) fp.write( "" "[epel-debuginfo]\n" "" ) fp.write( "" "name=ExtraPackagesforEnterpriseLinux6-$basearch-Debug\n" "" ) fp.write( "" "#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug\n" "" ) fp.write( "" "mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch\n" "" ) fp.write( "" "failovermethod=priority\n" "" ) fp.write( "" "enabled=0\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.write( "" "\n" "" ) fp.write( "" "[epel-source]\n" "" ) fp.write( "" "name=ExtraPackagesforEnterpriseLinux6-$basearch-Source\n" "" ) fp.write( "" "#baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS\n" "" ) fp.write( "" "mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch\n" "" ) fp.write( "" "failovermethod=priority\n" "" ) fp.write( "" "enabled=0\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.close() except: LOG(traceback.format_exc()) definstall_kvm_compute(self): try: os.system( "" "yum-yinstallkvmlibvirtqemuvirt-*" "" ) os.system( "" "yum-yinstalllrzszgccsysstatnet-snmp-*" "" ) os.system( "" "yum-yinstallopenstack-nova-computeopenstack-nova-networklibguestfs-winsupport" "" ) #ip=self.localIPaddr.split('.') #hostname="athCompute.%s.%s.autohome.com.cn"%(ip[2],ip[3]) #os.system("hostname%s"%hostname) #os.system("""sed-i's/^HOSTNAME=.*/HOSTNAME=%s/'/etc/sysconfig/network"""%hostname) os.system( "easy_installpsutil" ) os.system( "easy_installipdb" ) except: LOG(traceback.format_exc()) definstall_compute_source(self): try: cmd= "wget%s/athCloudOpenStack.tgz-O/opt/athCloudOpenStack.tgz" %self.URL x,y=commands.getstatusoutput(cmd) if x==0: os.chdir( '/opt/' ) os.system( "" "tar-xzvfathCloudOpenStack.tgz-C/" "" ) os.chdir(self.nova_path) if os.path.exists( 'nova.conf' ): shutil.move( 'nova.conf' , 'nova.conf.default' ) if os.path.exists( 'nova.conf.example' ): shutil.move( 'nova.conf.example' , 'nova.conf' ) self._nova_conf() self._start_nova_compute() else : LOG( "wgetathCloudOpenStack.tgzfalse" ) sys. exit () except: LOG(traceback.format_exc()) def_start_nova_compute(self): try: servers=[ 'openstack-nova-compute' , 'openstack-nova-network' , 'openstack-nova-extend' , 'libvirtd' ] for i in servers: os.system( "" "/sbin/service%srestart" "" %i) os.system( "" "/sbin/chkconfig%son" "" %i) except: LOG(traceback.format_exc()) def_nova_config(self): #Computenodenova.confinit try: fp= open ( '%s/nova.conf' %self.nova_path) f=fp.readlines() fp.close() for n,s in enumerate(f): if re.match( '#?glance_api_servers.*' ,s): f[n]= 'glance_api_servers=%s:9292\n' %self.masterIPaddr if re.match( '#?metadata_host.*' ,s): f[n]= 'metadata_host=%s\n' %self.masterIPaddr if re.match( '#?qpid_hostname.*' ,s): f[n]= 'qpid_hostname=%s\n' %self.masterIPaddr if re.match( '#?novncproxy_base_url.*' ,s): f[n]= 'novncproxy_base_url=http://%s:6080/vnc_auto.html\n' %self.masterIPaddr if re.match( '#?sql_connection.*' ,s): str=s. split ( '@' )[0]+ '@%s/nova' %self.masterIPaddr f[n]= '%s\n' %str if re.match( '#?my_ip.*' ,s): f[n]= 'my_ip=%s\n' %self.localIPaddr if re.match( '#?vncserver_listen.*' ,s): f[n]= 'vncserver_listen=%s\n' %self.localIPaddr if re.match( '#?vncserver_proxyclient_address.*' ,s): f[n]= 'vncserver_proxyclient_address=%s\n' %self.localIPaddr fp= open ( '%s/nova.conf' %self.nova_path, 'w' ) fp.writelines(f) fp.close() exceptException,e: LOG(traceback.format_exc()) if __name__== "__main__" : sc=DepolyCompute() sc.install_packstack() sc.install_kvm_compute() sc.install_compute_source() 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 #!/usr/bin/envpython #-*-coding:UTF-8-*- "" " @Item:InstallOpenstackCompute @Author:william @Group:NetworkSystemGroup @Date:2014-03-20 @Funtion: Function:DepolyOpenstackCompute... "" " import os,sys, time import traceback,shutil import commands import re defLOG(info): logfile= '/tmp/openstack_compute_install.log' files= open (logfile, 'a' ) try: files.write( '%s:%s' %( time .ctime(),info)) exceptIOError: files.close() files.close() classDepolyCompute(object): def__init__(self): print "PleasewriteinthescriptmasterIPpublicIPandlocalmanagement...\n" self.masterIPaddr= '192.168.220.1' self.localIPaddr= '192.168.220.1' self.URL= 'http://%s/source/' %self.masterIPaddr self.nova_path= '/etc/nova/' definstall_packstack(self): yum_path= '/etc/yum.repos.d/' #epel源目前不在更新OpenStackHavana版本,在下载源的时候默认已经移植了目录结构,需要重新安装RDO,在修改源路径,才能正常安装OpenStack等 comds= "https://repos.fedorapeople.org/repos/openstack/EOL/openstack-havana/rdo-release-havana-9.noarch.rpm" commands.getstatusoutput(cmd) try: cmd= "https://repos.fedorapeople.org/repos/openstack/EOL/openstack-havana/rdooo-release-havana-9.noarch.rpm" x,y=commands.getstatusoutput(cmd) if x!=0: fp= open ( '%s/rdo-release.repo' %yum_path, 'w' ) fp.write( "" "[openstack-havana]\n" "" ) fp.write( "" "name=OpenStackHavanaRepository\n" "" ) fp.write( "" "baseurl=https://repos.fedorapeople.org/repos/openstack/EOL/openstack-havana/epel-6/\n" "" ) fp.write( "" "enabled=1\n" "" ) fp.write( "" "skip_if_unavailable=0\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-RDO-Havana\n" "" ) fp.write( "" "priority=98\n" "" ) fp.close() cmd= "rpm-Uvhhttp://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm" x,y=commands.getstatusoutput(cmd) if x!=0: fp= open ( '%s/epel.repo' %yum_path, 'w' ) fp.write( "" "[epel]\n" "" ) fp.write( "" "name=ExtraPackagesforEnterpriseLinux6-$basearch\n" "" ) fp.write( "" "#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch\n" "" ) fp.write( "" "mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch\n" "" ) fp.write( "" "failovermethod=priority\n" "" ) fp.write( "" "enabled=1\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6\n" "" ) fp.write( "" "\n" "" ) fp.write( "" "[epel-debuginfo]\n" "" ) fp.write( "" "name=ExtraPackagesforEnterpriseLinux6-$basearch-Debug\n" "" ) fp.write( "" "#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug\n" "" ) fp.write( "" "mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch\n" "" ) fp.write( "" "failovermethod=priority\n" "" ) fp.write( "" "enabled=0\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.write( "" "\n" "" ) fp.write( "" "[epel-source]\n" "" ) fp.write( "" "name=ExtraPackagesforEnterpriseLinux6-$basearch-Source\n" "" ) fp.write( "" "#baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS\n" "" ) fp.write( "" "mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch\n" "" ) fp.write( "" "failovermethod=priority\n" "" ) fp.write( "" "enabled=0\n" "" ) fp.write( "" "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6\n" "" ) fp.write( "" "gpgcheck=1\n" "" ) fp.close() except: LOG(traceback.format_exc()) definstall_kvm_compute(self): try: os.system( "" "yum-yinstallkvmlibvirtqemuvirt-*" "" ) os.system( "" "yum-yinstalllrzszgccsysstatnet-snmp-*" "" ) os.system( "" "yum-yinstallopenstack-nova-computeopenstack-nova-networklibguestfs-winsupport" "" ) #ip=self.localIPaddr.split('.') #hostname="athCompute.%s.%s.autohome.com.cn"%(ip[2],ip[3]) #os.system("hostname%s"%hostname) #os.system("""sed-i's/^HOSTNAME=.*/HOSTNAME=%s/'/etc/sysconfig/network"""%hostname) os.system( "easy_installpsutil" ) os.system( "easy_installipdb" ) except: LOG(traceback.format_exc()) definstall_compute_source(self): try: cmd= "wget%s/athCloudOpenStack.tgz-O/opt/athCloudOpenStack.tgz" %self.URL x,y=commands.getstatusoutput(cmd) if x==0: os.chdir( '/opt/' ) os.system( "" "tar-xzvfathCloudOpenStack.tgz-C/" "" ) os.chdir(self.nova_path) if os.path.exists( 'nova.conf' ): shutil.move( 'nova.conf' , 'nova.conf.default' ) if os.path.exists( 'nova.conf.example' ): shutil.move( 'nova.conf.example' , 'nova.conf' ) self._nova_conf() self._start_nova_compute() else : LOG( "wgetathCloudOpenStack.tgzfalse" ) sys. exit () except: LOG(traceback.format_exc()) def_start_nova_compute(self): try: servers=[ 'openstack-nova-compute' , 'openstack-nova-network' , 'openstack-nova-extend' , 'libvirtd' ] for i in servers: os.system( "" "/sbin/service%srestart" "" %i) os.system( "" "/sbin/chkconfig%son" "" %i) except: LOG(traceback.format_exc()) def_nova_config(self): #Computenodenova.confinit try: fp= open ( '%s/nova.conf' %self.nova_path) f=fp.readlines() fp.close() for n,s in enumerate(f): if re.match( '#?glance_api_servers.*' ,s): f[n]= 'glance_api_servers=%s:9292\n' %self.masterIPaddr if re.match( '#?metadata_host.*' ,s): f[n]= 'metadata_host=%s\n' %self.masterIPaddr if re.match( '#?qpid_hostname.*' ,s): f[n]= 'qpid_hostname=%s\n' %self.masterIPaddr if re.match( '#?novncproxy_base_url.*' ,s): f[n]= 'novncproxy_base_url=http://%s:6080/vnc_auto.html\n' %self.masterIPaddr if re.match( '#?sql_connection.*' ,s): str=s. split ( '@' )[0]+ '@%s/nova' %self.masterIPaddr f[n]= '%s\n' %str if re.match( '#?my_ip.*' ,s): f[n]= 'my_ip=%s\n' %self.localIPaddr if re.match( '#?vncserver_listen.*' ,s): f[n]= 'vncserver_listen=%s\n' %self.localIPaddr if re.match( '#?vncserver_proxyclient_address.*' ,s): f[n]= 'vncserver_proxyclient_address=%s\n' %self.localIPaddr fp= open ( '%s/nova.conf' %self.nova_path, 'w' ) fp.writelines(f) fp.close() exceptException,e: LOG(traceback.format_exc()) if __name__== "__main__" : sc=DepolyCompute() sc.install_packstack() sc.install_kvm_compute() sc.install_compute_source() 本文转自 swq499809608 51CTO博客,原文链接:http://blog.51cto.com/swq499809608/1384332

资源下载

更多资源
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文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册