Roundup on Parallel Connections

[不指定 2012/06/28 09:21 | by ipaddr ]

A lot of blogging and follow-up discussion ensued with the announcement that IE8 supports six connections per host. The blogs I saw:

It’s likely that Firefox 3 will support 6 connections per server in an upcoming beta release, which means more discussion is expected. I wanted to pull all the facts into one place and make several points that I think are important and interesting. Specifically I talk about:

  • the HTTP/1.1 RFC
  • settings for current browsers
  • upperbound of open connections (cool!)
  • effect of proxies
  • will this break the Internet?


The HTTP/1.1 RFC

Section 8.1.4 of the HTTP/1.1 RFC says a “single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.” The key here is the word “should.” Web clients don’t have to follow this guideline. IE8 isn’t the first to exceed this guideline. Opera and Safari hold that honor supporting 4 connections per server.

It’s important to understand that this is on a per server basis. Using multiple domain names, such as 1.mydomain.com, 2.mydomain.com, 3.mydomain.com, etc., allows a web developer to achieve a multiple of the per server connection limit. This works even if all the domain names are CNAMEs to the same IP address.

Settings for Current Browsers

The table below shows the number of connections per server supported by current browsers for HTTP/1.1 as well as HTTP/1.0.

BrowserHTTP/1.1HTTP/1.0
IE 6,724
IE 866
Firefox 228
Firefox 366
Safari 3,444
Chrome 1,26?
Chrome 344
Chrome 4+6?
iPhone 24?
iPhone 36?
iPhone 44?
Opera 9.63,10.00alpha44
Opera 10.51+8?

I provide (some of) the settings for HTTP/1.0 in the table above because some of the blog discussions have confused the connections per server settings for HTTP/1.0 with those for HTTP/1.1. HTTP/1.0 does not have persistant connections so a higher number of connections per server is supported to achieve faster performance. For example, IE7 supports 4 connections per server in HTTP/1.0. In fact, AOL intentionally downgrades their responses to HTTP/1.0 to benefit from this increase in parallelization, although they do it at the cost of losing the benefits of persistent connections. They must have data that supports this decision, but I don’t recommend it.

It’s possible to reconfigure your browser to use different limits. How to configure Internet Explorer to have more than two download sessions describes how the MaxConnectionsPerServer and MaxConnectionsPer1_0Server settings in the Windows Registry control the number of connections per hostname for HTTP/1.1 and HTTP/1.0, respectively. In Firefox these values are controlled by the network.http.max-persistent-connections-per-server and network.http.max-connections-per-server settings in about:config.

Note that IE8 automatically drops back to 2 connections per server for users on dialup connections. Also, web developers can detect the number of connections per server currently in effect by accessing window.maxConnectionsPerServer and window.maxConnectionsPer1_0Server in JavaScript. These are read-only values.

Upperbound of Open Connections

What’s the maximum number of connections a browser will open?
This is relevant as server adminstrators prepare for spikes from browsers with increased parallelization.

This Max Connections test page contains 180 images split across 30 hostnames. That works out to 6 images per hostname. To determine the upperbound of open connections a browser supports I loaded this page and counted the number of simultaneous requests in a packet sniffer. Firefox 1.5 and 2.0 open a maximum of 24 connections (2 connections per hostname across 12 hostnames). This limit is imposed by Firefox’s network.http.max-connections setting which defaults to a value of 24.

In IE 6,7&8 I wasn’t able to determine the upperbound. At 2 connections per server, IE 6&7 opened 60 connections in parallel. At 6 connections per server, IE8 opened 180 connections in parallel. I’d have to create more domain names than the 30 I already have to try and find where IE maxes out. (If you load this in other browsers please post your results in a comment below and I’ll update this text.)

Effect of Proxies

Note that if you’re behind a proxy (at work, etc.) your download characteristics change. If web clients behind a proxy issued too many simulataneous requests an intelligent web server might interpret that as a DoS attack and block that IP address. Browser developers are aware of this issue and throttle back the number of open connections.

In Firefox the network.http.max-persistent-connections-per-proxy setting has a default value of 4. If you try the Max Connections test page while behind a proxy it loads painfully slowly opening no more than 4 connections at a time to download 180 images. IE8 drops back to 2 connections per server when it’s behind a proxy, so loading the Max Connections test page shows an upperbound of 60 open connections. Keep this in mind if you’re comparing notes with others – if you’re at home and they’re at work you might be seeing different behavior because of a proxy in the middle.

Will This Break the Internet?

Much of the debate in the blog comments has been about how IE8′s increase in the number of connections per server might bring those web servers to their knees. I found the most insightful comments in Mozilla’s Bugzilla discussion about increasing Firefox’s number of connections. In comment #22 Boris Zbarsky lays out a good argument for why this increase will have no effect on most servers. But in comment #23 Mike Hommey points out that persistent connections are kept open for longer than the life of the page request. This last point scares me. As someone who has spent many hours configuring Apache to find the right number of child processes across banks of servers, I’m not sure what impact this will have.

Having said that, I’m please that IE8 has taken this step and I’d be even happier if Firefox followed suit. This change in the client will improve page load times from the user’s perspective. It does put the onus on backend developers to watch closely as IE8 adoption grows to see if it affects their capacity planning. But I’ve always believed that part of the responsibility and joy of being a developer is doing extra work on my side that can improve the experience for thousands or millions of users. This is another opportunity to do just that.

I wrote before a guide Howto install Nginx/PHP-FPM on Fedora 16/15, CentOS/RHEL 6.1/6/5.7, but this guide is just installation guide and many cases Nginx and PHP-FPM basic configuration is good enough, but if you want to squeeze all the juice out of your VPS or web server / servers and do your maintenance work little bit easier, then this guide might be useful. These tips are based entirely on my own experience, so they may not be an absolute truth, and in some situations, a completely different configuration may work better. It’s also good to remember leave resources for another services also if you run example, MySQL, PostgreSQL, MongoDB, Mail server, Name server and/or SSH server on same machine.
And yes here we go…

Nginx Configuration and Optimizing Tips and Tricks


http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/

[转]知名网站的技术实现

[不指定 2012/06/14 14:15 | by ipaddr ]

网站需要具有良好的可伸缩性,来应对不断增长的访问量和数据量。《程序员》杂志5月刊的《可伸缩性的10年探索:知名网站的技术发展历程》一文中介绍了一些Alexa排名较前的网站的技术发展历程,本文将结合提及的Google、Facebook、Twitter等网站的技术发展历程,总结它们在可伸缩性、可用性、高性能以及低成本四点上通常采用的技术。

可伸缩

可伸缩分为垂直伸缩和水平伸缩两类,垂直伸缩通过升级机器的硬件来解决问题,水平伸缩通过增加机器来解决问题。不同网站在可伸缩上采用了不同的策略。例如,Google完全依赖水平伸缩来解决问题,而其他网站多数是依赖垂直伸缩来解决数据存储问题。

垂直伸缩要求软件要能在硬件升级时,发挥出硬件的能力,例如可配置的并行数、内存等。硬件的发展速度非常迅猛,网站的机器配置自然也是每年都在升级,因此软件时刻都在被检验是否能垂直伸缩。

水平伸缩主要解决的是如何仅通过增加机器就能解决问题,一般通过应用层和存储层两个层次来解决。

在应用层做到水平伸缩,通常采用的策略是Share Nothing/Stateless,将状态信息放入客户端或存储层(例如用户的会话信息放入Cookie,或放入服务器端的缓存系统)。此时,在访问量上涨后增加机器即可。在应用系统由单台增加到多台组成集群时,需要引入负载均衡,可能是硬件的也可能是软件的。

我们发现,就应用层的结构演变而言,前面提到的Google、Facebook、Twitter等网站在应用层上最后形成的结构几乎完全一样,均为前端Web系统集群 + Services集群。通常到了一定阶段后,前端Web系统和Services又会按照一定的规则来进行拆分,如按业务领域等。可见,其实SOA在大网站中已经落地,而不像企业领域中宣传的那么虚。

存储层实现水平伸缩,难度就比应用层大多了。从Google、Facebook、Twitter等几家网站的发展历程也可看出,解决存储层问题需要花费大量的时间和精力,而且由于业务发展的压力较大,很多网站开始会采用垂直伸缩方式来解决存储层的问题。

实现存储层的可伸缩性,通常采用的方案是单点写(指在某个粒度的单点,对HBase而言,单行数据一定在同一台机器上进行写操作),但读可能是多点。读多点,主要需要考虑不一致的问题。无论读是单点还是多点,数据都会在软件层面做到写多份,策略主要有同步写多份、投票写多份、异步复制最终一致等(例如HDFS、Cassandra、ZooKeeper),采用自动分裂方法来实现数据量增长时的自动伸缩,采用一致性Hash或根据某种规则的自动均衡策略等来实现机器增减时的相应处理,同时也需要有感知机器增减的方法(例如采用ZooKeeper)。

可以看出,要在存储层上实现可伸缩,技术上的难点很多。这也是为什么大规模网站都不在数据库上做复杂的运算,而只是把其当做一种存储信息的方式来使用。存储过程等基本不会出现,以降低数据库的压力。

除了应用层和存储层需要做到可伸缩外,在设计系统时硬件层面的可伸缩也是需要考虑的。例如,硬件负载设备只能支撑到一定流量,同样也要考虑如何让其能够可伸缩。

除了尽可能做到系统可伸缩外,减少对系统的压力也是缓解系统的可伸缩所面临挑战的方法,例如批量提交、最终一致、YouTube提到的“欺骗”、适当的正确性等策略。

可伸缩性是网站从小到大要经历的第一关挑战,同时随着网站的不断发展,还要不断地做技术改造才能保证网站在每个阶段(如同机房阶段、同城多机房阶段、异地多机房阶段)都具备优秀的可伸缩性。不过,幸运的是不同阶段的可伸缩性方案都已经比较成熟了。

可用性

可伸缩性能保证网站在访问量和数据量不断增长的情况下生存下来,同时也从某种程度上保证了网站的可用性。但除此之外,要保障系统的可用性,还需付出很多努力。

设计高可用性系统时,避免单点是其中最重要的一点,一般采用主备或集群等方法来避免单点。例如,负载均衡设备、MySQL等通常采用主备方式。在BigTable里采取了一种比较特殊的方法来避免Tablet Server的单点,即通过Chubby来感知Tablet Server的健康状况,如发现Tablet Server挂掉了,则由Master将此Tablet Server负责的Tablet迁移到其他的Tablet Server上。

除了避免单点外,降低耦合也是设计高可用性系统时应考虑的重点。通常采取异步化来降低耦合,将非关键逻辑和关键逻辑隔离开。例如,打开天猫的商品详情时,都会有相关商品的推荐。如果这个推荐系统出问题的话,就会导致商品详情也看不到了,因此这里可以异步载推荐系统,通常采用AJAX带超时的方式来实现。

Google、Facebook等网站在总结多年的可用性系统设计经验时,列入了同一条设计原则,即保持简单。简单的方案一般比较容易掌控,而复杂的方案一方面实现难度大,另一方面出现问题时很难排查。

可控性也是各网站强调的重点,可控性意味着一切代码都在掌控之下,并且最好是每个使用到的部分都由专业人员负责(对可用性要求越高,在这点上要求也就越高)。这样在出现问题时才能清楚是哪个地方造成的,并且可以自行排查和解决。如不可控,则意味着一旦出现问题,就得依赖第三方来排查,时间上非常不可控。这也是网站不愿意采用商用软件的重要原因。

编写高质量软件是保障系统高可用性的重要一环,可控性是其基础。Google、Facebook等网站在总结保障高可用的经验中均提到了监控/报警、容错、自我保护等策略。

监控/报警是软件自身能够保障高可用的重要策略,就像是汽车的仪表盘一样,可以告诉你油还剩多少、速度是多少、胎压是否正常等重要信息。对于软件而言,同样需要让外部获取到其运行的状况。例如,Google的软件都会提供一个HTML页面供使用者或开发人员访问(用过Hadoop的人也会发现这个特征)。在这个页面上可通过key/value的方式来获取系统的一些运行指标。对于RPC系统而言,Google会采集所有的正常请求、错误请求以及其消耗时间的分布状况(>0.05s、>0.1s等)。除了监控系统的运行状况外,也提供了其他一些方式以便外部能简单判断系统运行是否正常,例如cURL某页面等。对于不正常的现象,要及时报警,尽可能做到在故障尚未影响到用户时解决掉。

软件的正常运行需要依赖很多外部因素,例如机房、硬件、数据库、服务等,而所有依赖的部分都有可能出现故障(要坚信这点,互联网的特色是所有小概率事件都会发生)。在设计软件时需要考虑当依赖方出问题时,如何保障软件的可用性,因此一定要做一些容错处理。为了避免机房故障,各网站通常会租用或建设多机房。例如,Google采用IDE硬盘来存储文件,不做RAID,于是采用复制三份的策略来避免硬盘故障导致数据丢失。

软件一般会提供多种功能,有的重要、有的不重要的。而由不重要的功能异常导致重要的功能出现问题,显然不合算,因此在设计软件时需要充分考虑异常隔离,不互相影响。例如在Google的系统设计中会采用Prioritized Request等策略。

James Hamilton的那篇著名的论文《On Designing and Deploying Internet-Scale Services》中提到的Graceful Degradation,即为优雅降级。通常采用的方法是在故障将要出现或出现后,关闭系统的某些功能来降低故障产生的影响。例如,网站上有些操作可能特别耗资源,而这些资源的消耗又可能影响到核心功能,因此一旦出现影响,就可以关闭这些功能保障核心功能可用。降级可以帮助系统临时绕开故障,而产生故障的原因需要在事后排查。

交付具有高可用特征的软件是开发人员的重要职责。而对一个网站而言,软件不是一次性交付的,也不是好几年才升级一次,需要频繁交付,因此维护软件是保障高可用的重要环节。

多数情况下,系统的不可用是由变更造成的,因此如何降低变更对系统可用性造成的影响成为了各网站都关注的重点。Google在发布新产品时通常采取“滚木移石”方法,而Facebook则通常采用Dark Launch方法,降低变更带来的影响。

人工处理系统变更是故障产生的隐患,因此各网站基本都会推荐多种工具来实现系统变更的自动化,例如采用Puppet来实现自动化部署。

除了发布这个重要环节外,处理故障也是维护方面的重要工作。系统总有出现故障时,如何快速处理故障以降低对故障可用性的影响也成为网站一直关注的重点。前面已经讲述了可控性对解决故障的帮助。除可控性外,各网站也在研究其他方法。Facebook采用FBAR来自动处理部分故障,这显然可从某种程度上降低故障产生的影响。

性能

前面提到的可控性同样也是保证性能的重点,只有明确知道调用的每个API及所依赖环境(包括软硬件)的细节原理,才能编写出高性能软件。

从系统结构上来看,为了保障高性能,各大网站都采用了类似的方法。首先是前端Web系统这块,都采用了可编译为机器码的方式,即便Facebook采用的是PHP,其仍然研发了一个可自动转化为C++代码的产品来提升运行效率。

设计系统时,应考虑将没有前后依赖的逻辑并行化处理,或者将大的请求进行拆分。例如,Google会先将所搜索的内容进行分词,然后并行进行索引查询,从而提高响应速度。

基本上各大网站都极度依赖缓存,原因在于,内存的访问速度远快于磁盘。在依赖缓存的场景中,最需要做到的是数据一致性的合理保障。一个典型的场景是数据更新时保障缓存一致性的策略。要将缓存的更新和数据的更新做成一个事务显然有不小的难度,此时网站常采用一个简单的策略来保障,就是先失效缓存,再更新数据,等到下次系统去访问此数据时,才更新到内存。

除了缓存外,可以看到各大网站都采用了CDN,CDN可以让静态文件更靠近用户,便于用户快速获取。而除了让静态文件更靠近用户外,多IDC的建设除了提升可用性外,还可以让动态数据更靠近用户。当然,这在技术上的实现难度会比CDN高很多。

除了结构上的这几点外,技术创新是提升系统性能的重要方法。例如,Google提高了TCP的初始拥塞窗口值等。而要做到技术创新,显然可控性是基础。

成本

随着网站规模的不断扩大,系统的运行和维护成本将会成为公司中支出的重要部分。例如,有数据表明,腾讯每年支付给运营商的费用在总支出中占比排行第二(2010年为208亿)。网站规模越大,成本控制就越重要(潜台词是在网站规模不是很大时,也许支撑业务快速发展更重要)。例如,性价比是Google设计系统时重要考量的指标。有些网站会采用x元/每千次PV来计算成本。

有些性能优化需要增加成本(如缓存和CDN),而有些性能优化是可以降低成本的(如Google对索引结构的优化),因此性能优化通常也是降低成本的一种方法。网站规模大了以后,规模效应可以让有些性能优化带来的成本降低非常明显。

硬件不断升级,而软件系统层面上又更多的是靠集群来支撑,因此通常很难完全消耗硬件资源,虚拟化就成为一种不错的降低成本的方法。虚拟化具备很好的隔离机制,避免了应用间的互相影响,因此落地的难度不大。

除了依靠虚拟化来降低成本之外,Google采用了自行实现的一种Shared Environment方法来降低成本。Shared Environment可根据不同类型的资源消耗,动态组合(例如分时)部署到同一台机器上,充分利用资源。

如前所述,网站主要是靠可伸缩性存活下来的,因此随着规模的扩大,必然会有大量的机器。比如,Google有上百万台机器,Facebook有几十万台机器。在这么大规模下,自行根据应用特征设计机器,会带来很大的成本下降,因此Google、Facebook都自行设计机器和数据中心。从PUE上可以看出,Google、Facebook自行设计数据中心带来的成本降低非常可观。

各网站的情况不同,应对以上四点挑战所采用的方法不同,每个阶段都有自己适用的解决方案。例如,Google成立初期的主要业务是搜索,主要竞争的是技术,功能次之,而Facebook、eBay等网站的竞争压力主要在业务功能上,因此在成立之初必然会有不同的侧重点。不用想着一开始就把网站做成Google、Facebook等现在的结构,适合自己的就是好的。

很多开发人员在加入规模较大的网站后,会觉得系统结构已经稳定了,没有发展的空间,但从上面各网站的发展历程来看,可以看出网站对技术的要求是在不断演变的。通过观察大网站的发展历程,并结合公司的业务背景、知识结构等来判断其下一步的发展,对个人成长是有很大帮助的。同时可以借此储备一些技术,以把握技术演变时的机会,获得更大的成长。如果开发人员加入了规模尚小的网站,且自身技术储备不错的话,就有机会亲身经历网站从小到大的演变了。但这要看个人如何把握。

图1 发展到一定规模后的网站结构

围绕可伸缩性、可用性、性能和成本这四个方向,在网站发展到一定规模后,通常会演变成如图1所示的结构。

除了在可伸缩性、可用性、性能和成本这四方面的技术挑战外,网站还面临其他很多方面的挑战,例如海量数据分析和挖掘、网站安全、业务发展的灵活性支撑、人员增长后庞大的软件管理等,因此构建一个支撑大访问量、长期发展、低成本运行的网站是需要有坚实的技术背景作为支撑的。

作者林昊,目前就职于淘宝,2007-2010年负责设计和实现淘宝的服务框架,此服务框架在淘宝大面积使用,每天承担了150亿+的请求;2011年开始负责HBase在淘宝的落地,目前淘宝已有20个以上的在线项目在使用HBase。

升级RPM包的Spec文件调研

[不指定 2012/06/13 11:04 | by ipaddr ]

当在用户机器上安装或卸载程序时,能够执行命令将是很有用的。例如,可能需要编辑一个系统配置文件以启用新的服务,或者需要定义一个新用户以拥有正在安装的程序的所有权。

安装和卸载脚本的工作原理看起来很简单,但它们工作原理中的一些意外可能会引起大问题。这里是一些基本信息,可以将下列四节中的任意一个添加到.spec 文件,它列出了在包安装期间各个点上运行的shell 脚本:

%pre 在安装包之前运行

%post 在安装包之后运行

%preun 在卸载包之前运行

%postun 在卸载包之后运行

尤其要注意%install与这些节之间的差异。构建RPM 时,%install 在开发机器上运行;它应该将产品安装在开发机器上或安装到一个构建根目录中。另一方面,这些节指定当用户正在安装或卸载RPM包时将在用户的机器上运行什么。

一种好的技术是使用%pre脚本来检查安装前提条件,它们比RPM可以直接支持的更复杂。 如果不符合前提条件,那么脚本以非零状态退出,而且 RPM 不会继续安装。另外请注意,我们必须小心地使用卸载脚本来撤销安装脚本。

然而实际上没有那么简单:升级使每件事情都变得复杂,现在,让我们着手升级。如果用户只安装和删除自己的包,那么前面的指令将正常工作;但在升级期间,它们会完全失效。以下是 RPM 如何执行升级:

运行新包的 %pre

安装新文件

运行新包的 %post

运行旧包的 %preun

删除新文件未覆盖的所有旧文件

运行旧包的 %postun

如果我们使用5.3.2系列中现有SPEC文件中的脚本来升级,那么RPM最后将运行 %postun 脚本,它将除去我们在安装脚本中所做的所有工作。

rpm为了解决此问题,在其英文文档中提到了可以向脚本来传递一个参数$1,这个参数传递的过程是隐藏的,你只需在%pre%post%preun%postun中使用$1即可($1shell中就是第一个参数的意思)。这个参数的含义是在执行完此次操作后系统中此软件包的剩余数量是多少,就目前我的理解应该只有012三种可能。

1.在执行rpm –ivh的安装过程中,如果有同类包存在,则会报错提示无法安装,存在相同的文件。如果没有同类包存在则会执行安装动作,过程如下:

运行新包的%pre $1=1

安装新文件

运行新包的%post $1=1

2.在执行rpm –U的升级过程中,如果没有同类低级包存在,则过程和传递的参数与安装时完全相同,如果有同类低级包存在则会执行升级操作,过程如下:

运行新包的%pre $1=2

安装新文件

运行新包的%post $1=2

运行旧包的%preun $1=1

删除新文件未覆盖的任何旧文件

运行旧包的%postun $1=1

3.在执行rpm –e的删除过程如下:

运行旧包的%preun $1=0

删除文件

运行旧包的%postun $1=0

因此我们可以用传递的参数来判断rpm究竟在进行什么工作,来在脚本内部通过$1进行判断来决定进行什么动作。例如在参数为0的时候才真的执行卸载所要进行的动作。

另外在升级的时候,除了注意几个脚本的执行顺序与结果外,还要注意配置文件的处理是否正确,RPM还有一项重要的工作要做,这就是妥善处理配置文件(CONFIG FILE)。若直接采用安装方式,则用户已配置好的配置文件就会被覆盖,不符合用户要求。

RPM对某个配置文件,通过比较三种不同的MD5检查和(checksum)来决定如何处理它。这三种不同的MD5检查和是:

1. 原检查和。它是旧版本软件包安装时配置文件的MD5检查和。

2. 当前检查和。它是升级时旧版本配置文件的MD5检查和。

3. 新检查和。它是新版本软件包中配置文件的MD5检查和。

RPM针对以下几种情况分别处理:

1. 当原检查和=X,当前检查和=X,新检查和=X:

这表明配置文件未曾修改过。此时,RPM会将新的配置文件覆盖掉原文件,而不是对原文件不作处理,原因在于: 虽然文件名和文件内容都没有变化,但文件别的方面的属性(如文件的属主,属组,权限等)却可能改变,所以有必要覆盖一下。

2. 当原检查和=X,当前检查和=X,新检查和=Y:
这表明原配置文件没有改动过,但是它与新软件包中的配置文件却有所不同。这种情况下,RPM将用新文件覆盖掉旧文件,并且旧文件不作保存(因为它不曾改动过,没有必要保存)

3. 当原检查和=X,当前检查和=Y,新检查和=X:

这表明新文件与旧文件内容相同,但当前文件已经作过修改,这些修改对于新版本来说应该是合法的,可以使用的。因此,RPM对当前文件予以保留。

4. 当原检查和=X,当前检查和=Y,新检查和=Y:

这表明原文件经过修改,现在已与新文件相同,这或许是用户用来修补安全上的漏洞,新版本也作了同样的修改。这种情况下,RPM将新文件覆盖当前文件,避免文件属性方面的不同。

5. 当原检查和=X,当前检查和=Y,新检查和=Z:

这表明用户已修改了原文件,并且当前内容与新文件内容不同。这种情况下,RPM无法保证新版本软件能正常使用当前的配置文件,所以采用了一个比较明智的办 法,既能保护用户的配置数据,又能保证新版本软件正常。这种作法就是将当前文件换名保存(给原文件名加个.rpmsave的后缀,如原文件名为ABC,则 换名后为ABC.rpmsave),同时安装新文件,并给出警告信息。

6. 当没有原检查和时:

此种情况下,当前检查和与新检查和已无关紧要,这表明没有安装过此配置文件。因为没有安装过此配置文件,所以RPM无法判断当前文件是否被用户修改过。这种情况下,RPM会将当前文件换名保存(原文件名后缀不是加个.rpmsave,而是.rpmorig),同时安装新文件,并给出警告信息。

因此在%files中可以用%config字段将配置文件标识出来,这样在升级的过程中配置文件将被按照上面所描述的方法处理。

%config 文件路径的形式来添加。

分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]