首页 文章 精选 留言 我的

精选列表

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

Elasticsearch之es学习工作中遇到的坑

1:es集群脑裂问题(不要用外网ip,节点角色不要混用) 原因1:阿里云服务器,外网有时候不稳定。 解决方案:单独采购服务器,内网安装 原因2:master和node节点没有分开 解决方案: 分角色:master节点(三台),data节点(随着数据增加而增加),client(随着查询压力而增加)节点 Master节点:node.master: true node.data: false Data节点:node.master: false node.data: true Client 节点:node.master: false node.data: false 2:es集群名称的坑(1.4.x版本) 之前在使用1.4版本的时候,这个版本默认是多播协议,可以自动把同一网段的es节点组成一个集群。 所以,在刚开始使用的时候,多种业务部署了多个es集群,结果发现这几个集群莫名其妙搞到一块了。 建议:尽量不要使用集群的默认名称。 不过在2.x的版本中已经默认开启单播协议,不会自动增加同一网段的节点到一个集群。但是也建议修改一下集群名称,改完之后,如果使用java api进行操作,则必须设置cluster.name属性。 3:数据平衡,数据恢复(recover) 假设一个有10个节点的集群。 当重启集群的时候,在启动第二个节点的时候,集群之内的两个节点就开始恢复数据,相互生成副本,当启动第三个节点的时候,这三个节点又重新对数据进行恢复........... 这样非常浪费性能,导致在启动集群的过程当中,做了很多无用功,所以可以设置,当启动集群中5~6个节点的时候再允许进行数据恢复。 建议设置为集群节点数量的一半以上。 gateway.recover_after_nodes: 5 还有一点:es集群要使用内网ip,否则会出现数据恢复缓慢的现象。 4:定时优化索引片段很重要 开始的时候,没有对索引片段进行优化,查询延迟在3S以上,索引优化之后,延迟时间立刻降到1S以内。 5:内存溢出 修改elasticsearch.in.sh脚本 Master节点内存占用不多,CPU稍微高一点。 Data节点内存占用比较多,io操作比较频繁 Client:CPU和内存占用比较平均 6:集群插入数据报错 集群状态为yellow,索引副本数设置为2,但是只有一个节点存活,也就是没有产生副本。插入数据时报错。 7:设置jvm锁住内存时启动警告 当设置bootstrap.mlockall: true时,启动es报警告Unknown mlockall error 0,因为linux系统默认能让进程锁住的内存为64k。 解决方法:设置为无限制,linux命令:ulimit -l unlimited(立刻生效) 或者修改/etc/security/limits.conf(下一次重启开始,永久有效)文件 8:elk中,redis中数据堆积严重 调整logstash内存,使用批量方式向es中索引数据。 9:横向扩展es集群,不要纵向扩展 单纯增加es节点的内存和CPU不会有很大提升,建议多增加节点。 10:目前es集群部署情况 Master:3台(4 core ,16G内存,500G) 192.168.1.20 192.168.1.21 192.168.1.22 Data:8台(4 core 32G内存,2x1T) 192.168.1.31 192.168.1.32 192.168.1.33 192.168.1.34 192.168.1.35 192.168.1.36 192.168.1.37 192.168.1.38 Client:3台(4 core,32G,500G) 192.168.1.10 192.168.1.11 192.168.1.12 11、后续更新 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/6619108.html,如需转载请自行联系原作者

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

ASP.NET Core学习之二 菜鸟踩坑

对于像我这样没接触过core的人,坑还是比较多的,一些基础配置和以前差别很大,这里做下记录 一、Startup 1.注册服务 // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); // services.AddTransient<IUser, User>(); //services.AddSingleton<IUser>(new User()); services.AddSingleton<IUser, User>(); //services.AddScoped<>();//作用域注入 services.AddMemoryCache(); //MemoryCache缓存注入 } 2.配置HTTP请求管道 听起来很蒙,其实就是用于处理我们程序中的各种中间件,它必须接收一个IApplicationBuilder参数,我们可以手动补充IApplicationBuilder的Use扩展方法,将中间件加到Configure中,用于满足我们的需求。 // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } 3.自定义配置文件 类似于web.config ///IHostingEnvironment获取环境变量信息,没错就是获取环境变量 public Startup(IHostingEnvironment env) { //这里创建ConfigurationBuilder,其作用就是加载Congfig等配置文件 var builder = new ConfigurationBuilder() //env.ContentRootPath:获取当前项目的跟路径 .SetBasePath(env.ContentRootPath) //使用AddJsonFile方法把项目中的appsettings.json配置文件加载进来,后面的reloadOnChange顾名思义就是文件如果改动就重新加载 .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); //这返回一个配置文件跟节点:IConfigurationRoot Configuration = builder.Build(); } 二、Program 1. core1.0和2.0对比 core1.0和2.0的program写法是不一样的 .net core 1.0 public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .UseApplicationInsights() .Build(); host.Run(); } .net core 2.0 public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); 看一下WebHost.CreateDefaultBuilder(args)的源码: public static IWebHostBuilder CreateDefaultBuilder(string[] args) {var builder = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); if (env.IsDevelopment()) { var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); if (appAssembly != null) { config.AddUserSecrets(appAssembly, optional: true); } } config.AddEnvironmentVariables(); if (args != null) { config.AddCommandLine(args); } }) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); }) .UseIISIntegration() .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); }); return builder; } 可以看到2.0不过是被封装了,还集成了appsettings和日志的初始化。 sp.net core 自带了两种http servers, 一个是WebListener,在2.0中重命名为HTTP.sys , 可以使用来实现,它只能用于windows系统, 另一个是kestrel, 它是跨平台的. 2. Kestrel 支持特性 HTTPS Opaque upgrade used to enableWebSockets Unix sockets for high performance behind Nginx kestrel是默认的web server, 就是通过UseKestrel()这个方法来启用的. 但是我们开发的时候使用的是IIS Express, 调用UseIISIntegration(),启用IIS Express, 它作为Kestrel的Reverse Proxy server来用; 如果在windows服务器上部署的话, 就应该使用IIS作为Kestrel的反向代理服务器来管理和代理请求,和原IIS工作进程是分开的,通过ASP.NET Core Module(ANCM)来控制core程序; 此图 说明了IIS, ANCM 和ASP.NET Core 应用程序直接的关系 Requests come in from the Web and hit the kernel mode Http.Sys driver which routes them into IIS on the primary port (80) or SSL port (443). ANCM forwards the requests to the ASP.NET Core application on the HTTP port configured for the application, which is not port 80/443. Kestrel listens for traffic coming from ANCM. ANCM specifies the port via environment variable at startup, and theUseIISIntegrationmethod configures the server to listen onhttp://localhost:{port}. There are additional checks to reject requests not from ANCM. (ANCM does not support HTTPS forwarding, so requests are forwarded over HTTP even if received by IIS over HTTPS.) 注:大体意思是从80/443端口进来,然后ANCM通过 指定的端口 与程序进行交互,其中IISIntegration通过监听该端口,拒绝掉不是来自ANCM的请求。 如果在linux上的话, 可以使用apache, nginx等等的作为kestrel的proxy server,使用ForwardedHeaders中间件做处理,具体可以看官网怎么在linux下部署的文档; 当然也可以单独使用kestrel作为web 服务器, 但是使用iis作为reverse proxy还是由很多有点的: 例如,IIS可以过滤请求, 管理证书, 程序崩溃时自动重启等. 3. HTTP.sys HTTP.sys, 是通过UseKestrel()这个方法来启用的。但它不能与IIS 或者IIS Express 使用,也不能使用ANCM。 HTTP.sys 支持以下特性: Windows Authentication Port sharing HTTPS with SNI HTTP/2 over TLS (Windows 10) Direct file transmission Response caching WebSockets (Windows 8) 支持的Windows 版本: Windows 7 and Windows Server 2008 R2 and later 三、使用日志 public class HomeController : Controller { public HomeController() { ILoggerFactory loggerFactory = new LoggerFactory().AddConsole().AddDebug(); _logger = loggerFactory.CreateLogger<HomeController>(); _logger.LogInformation("================"); _logger.LogInformation("LOGGER IS START"); _logger.LogInformation("================"); } } 四、Routing 路由有两种方式: Convention-based (按约定), attribute-based(基于路由属性配置的). 其中convention-based (基于约定的) 主要用于MVC (返回View或者Razor Page那种的). Web api 推荐使用attribute-based. 这种基于属性配置的路由可以配置Controller或者Action级别, uri会根据Http method然后被匹配到一个controller里具体的action上. 常用的Http Method有: Get, 查询, Attribute:HttpGet, 例如: '/api/product', '/api/product/1' POST, 创建,HttpPost, '/api/product' PUT 整体修改更新HttpPut, '/api/product/1' PATCH 部分更新,HttpPatch, '/api/product/1' DELETE 删除,HttpDelete, '/api/product/1 还有一个Route属性(attribute)也可以用于Controller层, 它可以控制action级的URI前缀. 问题:继承api控制器后,只能使用Http Method,不能使用其他名称,或者是我不懂运用,比如GetUser 参考: http://blog.csdn.net/sd7o95o/article/details/78190862 http://blog.csdn.net/sd7o95o/article/details/78190862

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

Linux内核虚拟机 学习KVM架构及其优点

虚拟化概念很早就已出现。简单来说,虚拟化就是使用某些程序,并使其看起来类似于其他程序的过程。将这个概念应用到计算机系统中可以让不同用户看到不同的单个系统(例如,一台计算机可以同时运行 Linux 和 Microsoft® Windows®)。这通常称为全虚拟化(full virtualization)。 虚拟化也可以使用更加复杂的格式,其中单个计算机看上去具有多个架构(对于一个用户来说,它是一个标准的 x86 平台;对于另外一个用户来说,它是 IBM Power PC® 平台)。这种虚拟化形式通常被称为硬件仿真。 最后,更加简单的一种虚拟化是操作系统虚拟化,其中一台计算机可以运行相同类型的多个操作系统。这种虚拟化可以将一个操作系统的多个服务器隔离开来(这意味着全都必须使用相同类型和版本的操作系统)。 虚拟化和准虚拟化(para-virtualization) 虚拟化最常使用的两种方法是全虚拟化和准虚拟化。使用全虚拟化,在虚拟化的操作系统和硬件之间存在一个层,用于决定访问。这个层称为系统管理程序或虚拟机监视器(VMM)。准虚拟化与之类似,但是系统管理程序会以一种更具协作性的方式进行操作。这是因为每个客户操作系统都了解自己正在虚拟化模式中运行,因此每个系统都与系统管理程序协作,来实现底层硬件的虚拟化。 全虚拟化的例子包括商业虚拟化解决方案 VMware,以及商业 IBM zSeries® 计算机上使用的 IBM System z9 Virtual Machine(z/VM)操作系统。准虚拟化的例子有 Xen 和 User-Mode-Linux (UML)。 KVM 也被认为是一个全虚拟化解决方案,不过我们稍后再介绍这个问题。 虚拟化的工作原理 我们首先简要介绍一下虚拟化技术及其涉及的元素。虚拟化解决方案的底部是要进行虚拟化的机器。这台机器可能直接支持虚拟化,也可能不会直接支持虚拟化;那么就需要系统管理程序层的支持。系统管理程序,或称为 VMM,可以看作是平台硬件和操作系统的抽象化。在某些情况中,这个系统管理程序就是一个操作系统;此时,它就称为主机操作系统,如图 1所示。 图 1. 虚拟化的分层抽象 系统管理程序之上是客户机操作系统,也称为虚拟机(VM)。这些 VM 都是一些相互隔离的操作系统,将底层硬件平台视为自己所有。但是实际上,是系统管理程序为它们制造了这种假象。 处理器对于虚拟化的支持 由于平台虚拟化的优点非常有用,因此处理器供应商已经修改了自己的芯片来直接支持这种方法。这样做使处理器可以直接支持不同于客户机操作系 统的系统管理程序。对于 VMM 和 VM 来说,除了处理器状态(寄存器等)的管理不同之外,处理器还支持 I/O 和中断的虚拟化。要了解更多信息,请参看参考资料。 目前使用虚拟化解决方案的问题是,并非所有硬件都可以很好地支持虚拟化。较老的 x86 处理器根据执行范围对特定指令会产生不同结果。这就产生了一个问题,因为系统管理程序应该只能在一个最受保护的范围中执行。由于这个原因,诸如 VMWare 之类的虚拟化解决方案会提前扫描要执行的代码,从而将这些指令替换为一些陷阱指令(trap instruction),这样系统管理程序就可以正确地处理它们。Xen 可以支持一种协作的虚拟化方法,它不需要任何修改,因为客户机知道自己正在进行虚拟化,并已经进行了修改。KVM 会简单地忽略这个问题,如果您希望进行虚拟化,就强制必须在更新的硬件上运行。 刚开始会觉得这有些不方便,但是考虑到目前上市的较新机器都可以支持虚拟化(例如 Intel® VT 和 AMD SVM),用不了多久,这将成为标准方法而不是少数例外情况。有关可以支持虚拟化的处理器的更多信息,请参看参考资料和侧栏处理器对于虚拟化的支持。 KVM 系统管理程序 考虑到虚拟化技术的发展时间并不长,KVM 实际上还是一种相对来说比较新的技术。目前存在各具功能的开源技术,例如 Xen、Bochs、UML、Linux-VServer 和 coLinux,但是 KVM 目前正在被大量使用。另外,KVM 不再仅仅是一个全虚拟化解决方案,而将成为更大的解决方案的一部分。 KVM 所使用的方法是通过简单地加载内核模块而将 Linux 内核转换为一个系统管理程序。这个内核模块导出了一个名为/dev/kvm的设备,它可以启用内核的客户模式(除了传统的内核模式和用户模式)。有了 /dev/kvm 设备,VM 使自己的地址空间独立于内核或运行着的任何其他 VM 的地址空间。设备树(/dev)中的设备对于所有用户空间进程来说都是通用的。但是每个打开 /dev/kvm 的进程看到的是不同的映射(为了支持 VM 间的隔离)。 Linux 内核中 KVM 的源代码 您可以在 ./linux/drivers/kvm(V2.6.20 及更新版本)中找到 KVM 的源代码。这个目录包含了 KVM 的源文件,以及对于 Intel 和 AMD 扩展的处理器支持文件。 KVM 然后会简单地将 Linux 内核转换成一个系统管理程序(在安装 kvm 内核模块时)。由于标准 Linux 内核就是一个系统管理程序,因此它会从对标准内核的修改中获益良多(内存支持、调度程序等)。对这些 Linux 组件进行优化(例如 2.6 版本内核中的新 O(1) 调度程序)都可以让系统管理程序(主机操作系统)和 Linux 客户操作系统同时受益。但是 KVM 并不是第一个这样做的程序。UML 很久以前就将 Linux 内核转换成一个系统管理程序了。使用内核作为一个系统管理程序,您就可以启动其他操作系统,例如另一个 Linux 内核或 Windows 系统。 KVM 安装 KVM 之后,您可以在用户空间启动客户操作系统。每个客户操作系统都是主机操作系统(或系统管理程序)的一个单个进程。图 2提供了一个使用 KVM 进行虚拟化的视图。底部是能够进行虚拟化的硬件平台(目前指的是 Intel VT 或 AMD-SVM 处理器)。在裸硬件上运行的是系统管理程序(带有 KVM 模块的 Linux 内核)。这个系统管理程序与可以运行其他应用程序的普通 Linux 内核类似。但是这个内核也可以支持通过 kvm 工具加载的客户操作系统。最后,客户操作系统可以支持主机操作系统所支持的相同应用程序。 图 2. 使用 KVM 的虚拟化组件 记住 KVM 只是虚拟化解决方案的一部分。处理器直接提供了虚拟化支持(可以为多个操作系统虚拟化处理器)。内存可以通过 kvm 进行虚拟化(这在下一节中将会讨论)。最后,I/O 通过一个稍加修改的 QEMU 进程(执行每个客户操作系统进程的一个拷贝)进行虚拟化。 KVM 向 Linux 中引入了一种除现有的内核和用户模式之外的新进程模式。这种新模式就称为客户模式,顾名思义,它用来执行客户操作系统代码(至少是一部分代码)。回想一下内核模式表示代码执行的特权模式,而用户模式则表示非特权模式(用于那些运行 在内核之外的程序)。根据运行内容和目的,执行模式可以针对不同的目的进行定义。客户模式的存在就是为了执行客户操作系统代码,但是只针对那些非 I/O 的代码。在客户模式中有两种标准模式,因此客户操作系统在客户模式中运行可以支持标准的内核,而在用户模式下运行则支持自己的内核和用户 空间应用程序。客户操作系统的用户模式可以用来执行 I/O 操作,这是单独进行管理的。 在客户操作系统上执行 I/O 的功能是由 QEMU 提供的。QEMU 是一个平台虚拟化解决方案,允许对一个完整的 PC 环境进行虚拟化(包括磁盘、图形适配器和网络设备)。客户操作系统所生成的任何 I/O 请求都会被中途截获,并重新发送到 QEMU 进程模拟的用户模式中。 KVM 通过 /dev/kvm 设备提供了内存虚拟化。每个客户操作系统都有自己的地址空间,并且是在实例化客户操作系统时映射的。映射给客户操作系统的物理内存实际上是映射给这个进程 的虚拟内存。为了支持客户物理地址到主机物理地址的转换,系统维护了一组影子页表(shadow page table)。处理器也可以通过在访问未经映射的内存位置时使用系统管理程序(主机内核)来支持内存转换进程。 实例化新客户操作系统 新客户操作系统的实例化是由一个名为kvm的工具提供的。这个工具可以与 kvm 模块协同工作,使用 /dev/kvm 来加载客户操作系统,将它与虚拟磁盘(主机操作系统中的一个普通文件)关联起来,然后启动客户操作系统。 通过一组在 /dev/kvm 设备上执行的 ioctls 可以提供控制支持。当第一次打开这个特殊文件时,就会创建一个新的 VM 对象,它与一个虚拟 CPU 关联在一起。您然后可以使用几个 ioctls 来创建一个虚拟 CPU,检查 kvm 版本,创建内存区域,然后启动一个虚拟 CPU。您可以使用kvm命令实现这种功能。在接下来的几节中,我们将介绍kvm命令,并给出几个受支持的 ioctls 的示例。 使用 KVM 如果硬件支持的话,使用 KVM 实际上非常简单。您需要一个具有虚拟化支持的处理器。通过查看 /proc/cpuinfo 可以知道系统是否支持虚拟化。这个文件指定了是否支持 vmx(Intel)或 svm(AMD)扩展。 接下来,您需要一个启用了 KVM 支持的 Linux 内核。您可以在Device Drivers > Virtualization下的内核配置中完成这种配置。还必须启用处理器对环境的支持。另外,还必须具有 kvm 和 qemu 用户空间应用程序。更多信息请参见参考资料。 有了启用了虚拟化支持的引导内核,接下来的一个步骤是为客户操作系统创建一个磁盘映像。您可以使用qeumu-img来完成此操作,如下所示。注意这个映像的大小是 4GB,但是使用 QEMU 的写时复制格式(copy-on-write,qcow)时,整个文件将根据需要增长,而不是完全占据这 4 GB 的空间。 $ qemu-img create -f qcow vm-disk.img 4G 在创建虚拟磁盘之后,就可以将客户操作系统加载到其上。下面的例子假设客户操作系统是在 CD-ROM 上。除了使用 CD-ROM ISO 映像来填充虚拟磁盘之外,还必须在结束时启动这个映像。 $ kvm -no-acpi -m 384 -cdrom guestos.iso -hda vm-disk.img -boot d Ari Kivity 已经编写了一组测试工具来测试 KVM,而不需要全部的设备模型。下面的代码片断(来自于 kvm-12/user/main.c)从较高的层次上查看了 VM 的启动(请参见清单 1)。控制特性是由内核中的 ioctls 提供的(具体来说,在 ./linux-2.6.20/drivers/kvm/kvm_main.c 文件中)。 对kvm_init的调用会打开 /dev/kvm 设备,检查版本号(由 KVM 内核模块导出),然后分配一个 KVM 上下文对象并填充一些回调函数。kvm_create函数会建立并映射两个内存区域,然后使用 ioctl(KVM_CREATE_VCPU)创建一个虚拟 CPU(VCPU)。 load_file函数然后会将映像加载到给定的 VM 的地址空间中,然后调用kvm_run执行该 VM(使用 ioctlKVM_RUN)。尽管这个过程非常简单,但是它解释了如何使用 KVM 实例化新客户操作系统。 清单 1. 测试 KVM 系统管理程序的应用程序片断 int main() { void *vm_mem; kvm = kvm_init(&test_callbacks, 0); if (!kvm) { fprintf(stderr, "kvm_init failed\n"); return 1; } if (kvm_create(kvm, 128 * 1024 * 1024, &vm_mem) < 0) { kvm_finalize(kvm); fprintf(stderr, "kvm_create failed\n"); return 1; } if (ac > 1) if (strcmp(av[1], "-32") != 0) load_file(vm_mem + 0xf0000, av[1]); else enter_32(kvm); if (ac > 2) load_file(vm_mem + 0x100000, av[2]); kvm_show_regs(kvm, 0); kvm_run(kvm, 0); return 0; } 结束语 KVM 是解决虚拟化问题的一个有趣的解决方案,但是由于它是第一个进入内核的虚拟化解决方案,很难想象它会很快用于服务器虚拟化。还有其他一些方法一直在为进入 内核而竞争(例如 UML 和 Xen),但是由于 KVM 需要的修改较少,并且可以将标准内核转换成一个系统管理程序,因此它的优势不言而喻。 KVM 的另外一个优点是它是内核本身的一部分,因此可以利用内核的优化和改进。与其他独立的系统管理程序解决方案相比,这种方法是一种不会过时的技术。KVM 两个最大的缺点是需要较新的能够支持虚拟化的处理器,以及一个用户空间的 QEMU 进程来提供 I/O 虚拟化。但是不论好坏,KVM 位于内核中,这对于现有解决方案来说是一个巨大的飞跃。 本文转自 念槐聚 博客园博客,原文链接:http://www.cnblogs.com/haochuang/archive/2011/12/19/2293721.html,如需转载请自行联系原作者

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

docker学习笔记(五)——Docker常用命令总结

1. 开启/停止/重启container(start/stop/restart) 容器可以通过run新建一个来运行,也可以重新start已经停止的container,但start不能够再指定容器启动时运行的指令,因为docker只能有一个前台进程。 容器stop(或Ctrl+D)时,会在保存当前容器的状态之后退出,下次start时保有上次关闭时更改。而且每次进入attach进去的界面是一样的,与第一次run启动或commit提交的时刻相同。 1 2 3 CONTAINER_ID=$(dockerstart<containner_id>) dockerstop$CONTAINER_ID dockerrestart$CONTAINER_ID 关于这几个命令可以通过一个完整的实例使用:docker如何创建一个运行后台进程的容器并同时提供shell终端。 2. 连接到正在运行中的container(attach) 要attach上去的容器必须正在运行,可以同时连接上同一个container来共享屏幕(与screen命令的attach类似)。 官方文档中说attach后可以通过CTRL-C来detach,但实际上经过我的测试,如果container当前在运行bash,CTRL-C自然是当前行的输入,没有退出;如果container当前正在前台运行进程,如输出nginx的access.log日志,CTRL-C不仅会导致退出容器,而且还stop了。这不是我们想要的,detach的意思按理应该是脱离容器终端,但容器依然运行。好在attach是可以带上--sig-proxy=false来确保CTRL-D或CTRL-C不会关闭容器。 1 #dockerattach--sig-proxy=false$CONTAINER_ID 3. 查看image或container的底层信息(inspect) inspect的对象可以是image、运行中的container和停止的container。 1 2 3 4 查看容器的内部IP #dockerinspect--format='{\{.NetworkSettings.IPAddress}}'$CONTAINER_ID 172.17.42.35 (注:由于代码块解析的问题,上面NetworkSettings前面的\去掉) 4. 删除一个或多个container、image(rm、rmi) 你可能在使用过程中会build或commit许多镜像,无用的镜像需要删除。但删除这些镜像是有一些条件的: 同一个IMAGE ID可能会有多个TAG(可能还在不同的仓库),首先你要根据这些 image names 来删除标签,当删除最后一个tag的时候就会自动删除镜像; 承上,如果要删除的多个IMAGE NAME在同一个REPOSITORY,可以通过docker rmi <image_id>来同时删除剩下的TAG;若在不同Repo则还是需要手动逐个删除TAG; 还存在由这个镜像启动的container时(即便已经停止),也无法删除镜像; TO-DO 如何查看镜像与容器的依存关系 删除容器docker rm <container_id/contaner_name> 1 2 3 删除所有停止的容器 docker rm $(docker ps -a-q) 删除镜像docker rmi <image_id/image_name ...> 下面是一个完整的示例: 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 #dockerimages<== ubuntu13.10195eb90b53494monthsago184.6MB ubuntusaucy195eb90b53494monthsago184.6MB seanlook /ubuntu rm_test195eb90b53494monthsago184.6MB 使用195eb90b5349启动、停止一个容器后,删除这个镜像 #dockerrmi195eb90b5349 Errorresponsefromdaemon:Conflict,cannotdeleteimage195eb90b5349becauseitis tagged in multiplerepositories,use-ftoforce 2014 /11/04 14:19:00Error:failedtoremoveoneor more images 删除seanlook仓库中的tag<== #dockerrmiseanlook/ubuntu:rm_test Untagged:seanlook /ubuntu :rm_test 现在删除镜像,还会由于container的存在不能rmi #dockerrmi195eb90b5349 Errorresponsefromdaemon:Conflict,cannotdelete195eb90b5349becausethe containereef3648a6e77isusingit,use-ftoforce 2014 /11/04 14:24:15Error:failedtoremoveoneor more images 先删除由这个镜像启动的容器<== #dockerrmeef3648a6e77 删除镜像<== #dockerrmi195eb90b5349 Deleted:195eb90b534950d334188c3627f860fbdf898e224d8a0a11ec54ff453175e081 Deleted:209ea56fda6dc2fb013e4d1e40cb678b2af91d1b54a71529f7df0bd867adc961 Deleted:0f4aac48388f5d65a725ccf8e7caada42f136026c566528a5ee9b02467dac90a Deleted:fae16849ebe23b48f2bedcc08aaabd45408c62b531ffd8d3088592043d5e7364 Deleted:f127542f0b6191e99bb015b672f5cf48fa79d974784ac8090b11aeac184eaaff 注意,上面的删除过程我所举的例子比较特殊——镜像被tag在多个仓库,也有启动过的容器。按照<==指示的顺序进行即可。 5. docker build使用此配置生成新的image build命令可以从Dockerfile和上下文来创建镜像:docker build [OPTIONS] PATH | URL | - 上面的PATH或URL中的文件被称作上下文,build image的过程会先把这些文件传送到docker的服务端来进行的。 如果PATH直接就是一个单独的Dockerfile文件则可以不需要上下文;如果URL是一个Git仓库地址,那么创建image的过程中会自动git clone一份到本机的临时目录,它就成为了本次build的上下文。无论指定的PATH是什么,Dockerfile是至关重要的,请参考Dockerfile Reference。 请看下面的例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #catDockerfile FROMseanlook /nginx :bash_vim EXPOSE80 ENTRYPOINT /usr/sbin/nginx -c /etc/nginx/nginx .conf&& /bin/bash #dockerbuild-tseanlook/nginx:bash_vim_Df. SendingbuildcontexttoDockerdaemon73.45MB SendingbuildcontexttoDockerdaemon Step0:FROMseanlook /nginx :bash_vim --->aa8516fa0bb7 Step1:EXPOSE80 --->Usingcache --->fece07e2b515 Step2:ENTRYPOINT /usr/sbin/nginx -c /etc/nginx/nginx .conf&& /bin/bash --->Running in e08963fd5afb --->d9bbd13f5066 Removingintermediatecontainere08963fd5afb Successfullybuiltd9bbd13f5066 上面的PATH为.,所以在当前目录下的所有文件(不包括.dockerignore中的)将会被tar打包并传送到docker daemon(一般在本机),从输出我们可以到Sending build context...,最后有个Removing intermediate container的过程,可以通过--rm=false来保留容器。 TO-DOdocker build github.com/creack/docker-firefox失败。 6. 给镜像打上标签(tag) tag的作用主要有两点:一是为镜像起一个容易理解的名字,二是可以通过docker tag来重新指定镜像的仓库,这样在push时自动提交到仓库。 1 2 3 4 将同一IMAGE_ID的所有tag,合并为一个新的 #dockertag195eb90b5349seanlook/ubuntu:rm_test 新建一个tag,保留旧的那条记录 #dockertagRegistry/Repos:TagNew_Registry/New_Repos:New_Tag 7. 查看容器的信息container(ps) docker ps命令可以查看容器的CONTAINER ID、NAME、IMAGE NAME、端口开启及绑定、容器启动后执行的COMMNAD。经常通过ps来找到CONTAINER_ID。docker ps默认显示当前正在运行中的containerdocker ps -a查看包括已经停止的所有容器docker ps -l显示最新启动的一个容器(包括已停止的) 8. 查看容器中正在运行的进程(top) 容器运行时不一定有/bin/bash终端来交互执行top命令,查看container中正在运行的进程,况且还不一定有top命令,这是docker top <container_id/container_name>就很有用了。实际上在host上使用ps -ef|grep docker也可以看到一组类似的进程信息,把container里的进程看成是host上启动docker的子进程就对了。 9. docker与宿主机文件互拷 将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下。 1 docker cp /www/runoob 96f7f14e99ab: /www/ 将主机/www/runoob目录拷贝到容器96f7f14e99ab中,目录重命名为www。 1 docker cp /www/runoob 96f7f14e99ab: /www 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。 1 docker cp 96f7f14e99ab: /www /tmp/ 10、docker 容器保持后台运行的两种方式 10.1run一个容器: (推荐方法) 1 2 3 4 5 [root@localhost~] #dockerrun-dit--hostnamecentos--namecentos--restartalwaysa8493f5f50ff/bin/bash -dit是后台运行、交互模式、分配终端,容器启动后不会退出 如果没有it参数,run一个容器以后,docker ps -a容器状态就exited了 --restartalways容器可以随docker服务启动而启动 10.2run 一个容器,并一直发送ping包 1 [root@localhost~] #dockerrun-d--nametest--hostnametesta8493f5f50ffping127.0.0.1 开启ping进程,则主机一直运行 本文转自 jackjiaxiong 51CTO博客,原文链接:http://blog.51cto.com/xiangcun168/1958278

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

docker学习笔记(四)——Dockerfile创建自定义镜像

用Dockerfile创建docker,注意下,建议在空文件夹下创建 本篇我们将完成: 1、用Dockerfile创建docker 2、端口映射 3、卷挂载,即docker目录挂载到宿主机 1、用Dockerfile创建docker 在/opt/centos/目录下,创建Dockerfile 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 #CentosbasedcontainerwithJavaandTomcat FROM127.0.0.1:5000 /centos :v2 #镜像源,这里为私有 MAINTAINERjack.zhang #作者 ENVREFRESHED_AT2017-8-28 #日期 #Prepareenvironment#声明创建变量 ENVJAVA_HOME /opt/jdk1 .8.0_131 ENVJRE_HOME /opt/jdk1 .8.0_131 /jre ENVCLASSPATH.:$JAVA_HOME /lib :$JRE_HOME /lib :$CLASSPATH ENVPATH$JAVA_HOME /bin :$JRE_HOME /bin :$PATH RUN mkdir /data RUNyum install -ywget #建议搭建本地软件源,取包比较快,当时直接yum安装也可以,前提宿主机可以上网 RUNwgethttp: //192 .168.10.144:9098 /jdk-8u131-linux-x64 . tar .gz&&\ #下载10.144安装包 tar -xvfjdk-8u131-linux-x64. tar .gz-C /opt/ #InstallTomcat RUNwgethttp: //192 .168.10.144:9098 /tomcat . tar .gz&&\ tar -xvftomcat. tar .gz-C /data/ &&\ mv /data/tomcat /data/tomcat8 RUN chmod +x /data/tomcat8/bin/ *sh VOLUME[ "/data/tomcat8/webapps/" ] EXPOSE8090 #对外暴露的端口,即对外提供服务的端口 EXPOSE8009 ENTRYPOINT[ "/data/tomcat8/bin/catalina.sh" , "run" ] #启动tomcat,注意,docker里面的进程要一直挂起,要不然会退出,我们用这种办法启动 文件编辑完成后,我们来生成docker 1 2 3 4 5 6 7 8 9 注意命令后有个点,不要忘记,当前文件夹下面一定有Dockerfile #dockerbuild-ttest/test_app. 会打印一堆日志,这不影响,如果有异常可以找出对应问题, 创建后,我们看下是不是已经成功了 #dockerimages REPOSITORYTAGIMAGEIDCREATEDSIZE test /test_app latest29175ec8a72017hoursago836MB 2、端口映射 因为上面的端口已经暴露出来,只要tomcat启动了,端口就是通的,所以我们这里要做的就是启动docker并把端映射出来,这里的8090是docker提供服务的端口 1 2 3 4 5 6 7 启动docker并映射端口注意,-p就是端口映射 #dockerrun-d-p8090:8090--restart=always--nametomcattest/test_app 看下进程是否启动成功 #dockerps CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 923bc1dda78f test /test_app "/data/tomcat8/bin..." 29minutesagoUp29minutes8009 /tcp ,0.0.0.0:8090->8090 /tcp tomcat 用宿主机访问IP:端口,访问是不是可以访问到了? 需要说明的是,端口映射其它是基于iptables的,所以如果docker启动没问题,进程也存在,确认宿主机的iptables 是否启动 centos iptables 1 #systemctlstartfirewalld.service#启动firewall 3、卷挂载,即docker目录挂载到宿主机 其它挂载目录到宿主机,没什么特别的,有些文档介绍的好像有多么深奥,其实没啥 只是启动命令加下参数罢了, 先关闭运行中的docker 1 #dockerstop923bc1dda78f923bc1dda78f是docker的进程号,通过dockerps可以看得到 好了,挂载目录启动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - v 命令,注意前面的是宿主机的目录,后面提docker目录 即把宿主机的 /usr/share/nginx/html 挂载到docker的 /data/tomcat8/webapps/ROOT/ 下 #dockerrun-d-v/usr/share/nginx/html:/data/tomcat8/webapps/ROOT-p8090:8090--restart=always--nametomcatapptest/test_app 查看下进程 #dockerps CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 923bc1dda78f test /test_app "/data/tomcat8/bin..." 29minutesagoUp29minutes8009 /tcp ,0.0.0.0:8090->8090 /tcp tomcat 我们进入到dockershell看下是不是成功挂载 #dockerexec-it923bc1dda78f/bin/bash#923bc1dda78f为进程号 [root@923bc1dda78f/] #cd/data/tomcat8/webapps/ROOT/ [root@923bc1dda78fROOT] #ls 404.html50x.htmlapache-tomcat-8.5.15-src. tar .gzindex.htmljdk-8u131-linux-x64. tar .gznginx-logo.pngpoweredby.png 可以看到已经功能挂载 直接访问宿主机:端口,是不是首页不一样的~~ 这样是不是很方便了,我们直接维护宿主机的目录就相当于维护docker目录。 本文转自 jackjiaxiong 51CTO博客,原文链接:http://blog.51cto.com/xiangcun168/1958270

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

开源中国iOS客户端学习——(七)MBProgressHUD特效

在开源中国iOS客户端中也用到了MBProgressHUD这个特效,主要作用为应用显示一个过渡的作用,常用于打开一个联网页面加载过程,防止出现假死现象,如果网速慢则告诉用户已经在很努力很努力的加载中。 GitHub上下载地址:https://github.com/jdg/MBProgressHUD 源码中也自带了一个Demo,显示13中动画效果,可以根据需要选取其中特效加以使用,使用方法基本一样;使用的时候只加把MBProgressHUD.h和MBProgressHUD.m拖入工程中,在使用的文件中加上#import"MBProgressHUD.h" 在开源中国iOS客户端中只用到一种特效,当我们选取一条资讯查看详细信息时: 我们在跳转到实现的代码部分,在NewsDetail.m的clickFavorite和viewDidLoad方法中 - (void)clickFavorite:(id)sender { UIBarButtonItem * btn = (UIBarButtonItem *)sender; BOOL isFav = [btn.title isEqualToString:@"收藏此文"]; MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:self.view]; [Tool showHUD:isFav ? @"正在添加收藏":@"正在删除收藏" andView:self.view andHUD:hud]; [[AFOSCClient sharedClient]getPath:isFav ? api_favorite_add : api_favorite_delete parameters:[NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithFormat:@"%d", [Config Instance].getUID],@"uid", [NSString stringWithFormat:@"%d", newsID],@"objid", @"4",@"type", nil] success:^(AFHTTPRequestOperation *operation, id responseObject) { [hud hide:YES]; [Tool getOSCNotice2:operation.responseString]; ApiError *error = [Tool getApiError2:operation.responseString]; if (error == nil) { [Tool ToastNotification:operation.responseString andView:self.view andLoading:NO andIsBottom:NO]; return ; } switch (error.errorCode) { case 1: { btnFavorite.title = isFav ? @"取消收藏" : @"收藏此文"; self.singleNews.favorite = !self.singleNews.favorite; } break; case 0: case -2: case -1: { [Tool ToastNotification:[NSString stringWithFormat:@"错误 %@",error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO]; } break; } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { [hud hide:YES]; [Tool ToastNotification:@"添加收藏失败" andView:self.view andLoading:NO andIsBottom:NO]; }]; } - (void)viewDidLoad { [super viewDidLoad]; self.tabBarItem.title = @"资讯详情"; self.tabBarItem.image = [UIImage imageNamed:@"detail"]; //WebView的背景颜色去除 [Tool clearWebViewBackground:self.webView]; self.singleNews = [[SingleNews alloc] init]; self.navigationController.title = @"资讯详情"; self.webView.delegate = self; [self.webView loadHTMLString:@"" baseURL:nil]; if ([Config Instance].isNetworkRunning) { MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:self.view]; [Tool showHUD:@"正在加载" andView:self.view andHUD:hud]; NSString *url = [NSString stringWithFormat:@"%@?id=%d",api_news_detail, newsID]; [[AFOSCClient sharedClient] getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { [Tool getOSCNotice2:operation.responseString]; [hud hide:YES]; self.singleNews = [Tool readStrNewsDetail:operation.responseString]; if (self.singleNews == nil) { [Tool ToastNotification:@"加载失败" andView:self.view andLoading:NO andIsBottom:NO]; return; } [self loadData:self.singleNews]; //如果有网络 则缓存它 if ([Config Instance].isNetworkRunning) { [Tool saveCache:1 andID:self.singleNews._id andString:operation.responseString]; } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { [hud hide:YES]; if ([Config Instance].isNetworkRunning) { [Tool ToastNotification:@"错误 网络无连接" andView:self.view andLoading:NO andIsBottom:NO]; } }]; } else { NSString *value = [Tool getCache:1 andID:newsID]; if (value) { self.singleNews = [Tool readStrNewsDetail:value]; [self loadData:self.singleNews]; } else { [Tool ToastNotification:@"错误 网络无连接" andView:self.view andLoading:NO andIsBottom:NO]; } } } 分析viewDidLoad方法, 首先是判断网络是否连通状态,如果是 定义在当前的view中定义一个MBProgressHUD对象,进行初始化 [ToolshowHUD:@"正在加载"andView:self.viewandHUD:hud];是在Tool类里面进行的一次封装,设置MBProgressHUD的显示信息 + (void)showHUD:(NSString *)text andView:(UIView *)view andHUD:(MBProgressHUD *)hud { [view addSubview:hud]; hud.labelText = text;//显示提示 hud.dimBackground = YES;//使背景成黑灰色,让MBProgressHUD成高亮显示 hud.square = YES;//设置显示框的高度和宽度一样 [hud show:YES]; } 然后在用到AFNetWork类库的getPath:parameters:success:failure:方法,嵌套在block块中判断请求的url是否成功,在执行[Tool getOSCNotice2:operation.responseString];这个方法也是封装在Tool类中,封装的是TBXML解析器,如果解析成功立即设置MBProgressHUD隐藏属性[hud hide:YES];如果请求的url不成功直接设置MBProgressHUD隐藏属性[hud hide:YES],再用GCDiscreetNotificationView进行通知“错误 网络无连接”; 本文转自新风作浪 51CTO博客,原文链接:http://blog.51cto.com/duxinfeng/1208683,如需转载请自行联系原作者

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

netapp学习(十二)---Dedup:file-level or block-level??

公司开始搞分布式数据库了,接下来的时间正好有机会接触Hadoop,以前简单的以为Hadoop只是个简单的HDFS,现在才发现Hadoop包括HDFS/MapReduce,再加上Hbase。就有了cloud computing的基础。 这两天就把之前做过的关于DataOntap和Celerra的dedup的实验贴出来,最近也就没时间研究其他东西了。 DataOntap的文档中说它是SIS,即single instance stroage,即单实例存储,所以就是文件级的dedup。下面就来验证它到底是不是SIS? 1、看下现在存储(vol1)的容量,使用101MB 2、101M只包括只有如下文件 3、现在增加2.exe(2.exe和1.exe是完全一样的文件) 4、可以看到由101MB增加到105MB 5、开始做dedup,如果确如文档中所说它是SIS,那么容量应该会减少,至少不是现在的105M DataOnTap2&gt; sis status No status entry found. DataOnTap2&gt; sis on /vol/vol1 SIS for "/vol/vol1" is enabled. Already existing data could be processed by running "sis start -s /vol/vol1". DataOnTap2&gt; sis start -s /vol/vol1 The file system will be scanned to process existing data in /vol/vol1. This operation may initialize related existing metafiles. Are you sure you want to proceed (y/n)? y The SIS operation for "/vol/vol1" is started. DataOnTap2&gt; Sat Oct 8 02:21:27 GMT [DataOnTap2: wafl.scan.start:info]: Starting SIS volume scan on volume vol1. Sat Oct 8 02:21:52 GMT [DataOnTap2: wafl.snap.delete:info]: Snapshot copy sis.5d9cd2b6-e429-11e0-8fc5-005056a5000b on volume vol1 NetApp was deleted by the Data ONTAP function dense_delete_snapshot. The unique ID for this Snapshot copy is (1, 20964). 6、做完SIS后发现容量确实变成了102M 从108404KB减少到104344KB 上面已经证明了DataOntap8确实是SIS,那么会不会是块级别或者是字节级别的dedup呢?为此,有了下面的实验 1、先上传wafl-overview.ppt,容量为103MB 2、再上传wafl-overview-2.ppt(wafl-overview-2.ppt比 wafl-overview.ppt多了2页),做dedup之前大小为103MB,105996KB 3、开始dedup,如果是block-level或byte-level的,那么大小应该经dedup后小于105996KB DataOnTap2&gt; sis start -s /vol/vol1 The file system will be scanned to process existing data in /vol/vol1. This operation may initialize related existing metafiles. Are you sure you want to proceed (y/n)? y The SIS operation for "/vol/vol1" is started. DataOnTap2> Sat Oct 8 03:18:25 GMT [DataOnTap2: wafl.scan.start:info]: Starting SIS volume scan on volume vol1. DataOnTap2> Sat Oct 8 03:18:53 GMT [DataOnTap2: wafl.snap.delete:info]: Snapshot copy sis.5d9cd2b6-e429-11e0-8fc5-005056a5000b on volume vol1 NetApp was deleted by the Data ONTAP function dense_delete_snapshot. The unique ID for this Snapshot copy is (2, 20983). 4、经过dedup并没有改变 通过以上的实验说明,DataOntap8确实是file-level的SIS,并不是block-level或byte-level的。可能有人会有疑问:上面的2个PPT的实验文件太小,可能采用的block-level的技术,而文件大小没有达到block-level的block大小。但是据我所知,如果是block-level的,不管是定长还是不定长,都不会超过上面的412KB吧。所以只要是block-level的,它肯定会进行切分,并删除重复的部分。所以DataOntap8只是file-level的。 下次把celerra的dedup实验贴出来。。。。。 本文转自 taojin1240 51CTO博客,原文链接:http://blog.51cto.com/taotao1240/688699,如需转载请自行联系原作者

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

Android 利用【Hierarchy Viewer 】 工具学习别人的UI设计

在Android 工具栏里面,地址:D:\Program Files\android-sdk-windows\tools 目录下打开此工具 此工具名为:层级观察器 本篇文章将教大家如何利用层级观察器查看和优化自己的UI层次关系或者看别人应用程序UI的布局结构,双击该处理文件,显示如下 图: 左边为设备列表名称,如果你开启多个设备将会一一列出你当前运行的设备,包括真机。 右边是当前设备列表运行的Acitivity ,即你当前运行的Activity 对应的UI布局,本篇将使用Android 自身的音乐播放器,来操作得到UI布局结构,这里的我们要点击 com.android.music/com.android.music.MediaPlaybackActivity 项,选中它,到上面点击Load View Hierarchy 项,右下角将会出现加载进度条,然后将加载的View 结构显示出来,如下图: 左边为UI 的关系图 右边为每个View 的属性(必须选中任意View 对象)和结构草图底下是关系图的缩略图 底下进度条可以控制关系的显示大小 左下角两个按钮为缩略显示和列表显示方式,先把列表显示方式为如下图: 左边为布局中使用的ViewGroup和View 的关系结构图,点中任意的一个View 对象右边都会帮我们获得焦点 右边为显示当前Activity 在真机运行的效果图,我记得有个朋友在QQ群问过,有没有什么工具可以得到坐标的,其实这个工具就可以坐到,看最右下角,分别为RGB 和XY 轴,我们点击屏幕的任意为置,它都会帮我们算出来当前显示的值,怎么样是不是很实用的一个工具。快去试试吧 Tip:最上边的导航还可以帮们把VIEW结构生成PSD图或者做快速的切换设备动作。 本文转自 terry_龙 51CTO博客,原文链接:http://blog.51cto.com/terryblog/386568,如需转载请自行联系原作者

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

Android开发学习:在Eclipse中导入Android项目方法

在Eclipse中导入Android项目方法的具体步骤如下: 1.启动Eclipse,依次选择File---Import,如下图所示: 2.在弹出的Import窗口中选择Existing Projects into Workspace,然后单击Next按钮,如下图所示: 3.在弹出的Import窗口选择Browse按钮,选择要导入项目的位置,如下图所示: 4.单击Finish按钮后,完成整个导入过程,在eclipse中讲显示这个导入的实例,如下如所示 5.需要运行这个项目,依次选择Run---Run Configurations 6.在弹出的窗口中设置标志名,再选择Browse文件功能和项目位置 7.单击Run后开始运行这个项目 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/667705

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

android学习之-TextView内容及颜色的修改方法

主类 packagesucre.android; importandroid.app.Activity; importandroid.content.res.Resources; importandroid.graphics.Color; importandroid.graphics.drawable.Drawable; importandroid.os.Bundle; importandroid.widget.TextView; /** *给TextView变色的两种方法:一是直接读取写好的配置文件,二是在类中获取TextView直接用setBackground**进行修改 *可以对TextView原先的内容进行添加,这里用到了CharSequence *@authorqiaolei * */ publicclassEXT03_02extendsActivity{ /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); //获取资源 Resourcesre=getBaseContext().getResources(); //从资源中获取drawable Drawableda=re.getDrawable(R.drawable.red); //将main.xml中定义的myTextViewTest取出 TextViewtv=(TextView)findViewById(R.id.myTextViewTest); //将定义的textview的背景图片换成指定颜色 tv.setBackgroundDrawable(da); //也可以直接设置文本的颜色 tv.setTextColor(Color.BLACK); //对TextView的内容进行修改 //读取字符串hello中的内容 CharSequencestr=getString(R.string.hello); //要进行添加的内容 Stringstr_1="我是后添加上的内容"; //将拼接好的内容赋给原先的TextView tv.setText(str+str_1); } } main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/white" > <TextView android:id="@+id/myTextViewTest" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:textColor="@drawable/blue" /> </LinearLayout> color.xml <?xmlversion="1.0"encoding="UTF-8"?> <resources> <colorname="white">#ffffff</color> <colorname="black">#000000</color> <drawablename="red">#ff0000</drawable> <drawablename="blue">#0000ff</drawable> </resources> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,EXT03_02!</string> <stringname="app_name">EXT03_02</string> </resources> 以上是我在看书的时候跟着例子做的,有些东西书上是没有的我就自己加上了,因为自己也是刚接触android开发,所以例子有些简单,但是备份一下,以后用的着。 本文转自sucre03 51CTO博客,原文链接:http://blog.51cto.com/sucre/742803,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

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

Nacos

Nacos

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

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

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

用户登录
用户注册