Cloudflare
注意,测试过程最少需要 24 小时。在各个时区,互联网的表现会随着用户作息或者 Netflix 的使用情况等发生变化。所以要测试一个国家,需要完整的一天数据。最好是在工作日(而不要半天落在周六)。我们知道会有各种意外情况。互联网的性能并不是稳定的,我们要通过数据来证明这一点。
我们最初的假设是,多增加了的一个节点会带来额外的延时,我们会因此损失一部分页面加载性能。但是 DNS 性能上的增加其实弥补了这一块。比起我们只有一个数据中心来说,Cloudflare 的 DNS 服务器部署在离用户更近的地方,这一块性能要好得多得多。我希望我们能有空来放出这一块的数据,只不过这一块需要很多处理(以及托管),而我现在也没有足够多的时间。
Cloudflare: Railgun
举个例子,想象一下,两个用户打开同一个问题的页面。从浏览效果来看,他们的页面技术上长得几乎一样,仅仅有细微的差别。如果我们大部分的传输内容只是一个 diff 的话,这将是一个巨大的性能提升。
Fastly
事实胜于雄辩:如果我不认可 Cloudflare,我的私人博客不可能选择它,嘿,就是这个博客,你现在正在阅读的。
sub vcl_fetch {
if (beresp.http.Cache-Control) {
if (req.url.path ~ "^/users/flair/") {
set beresp.http.Cache-Control = "public, max-age=180";
} else {
set beresp.http.Cache-Control = "private";
}
}
另一个 Fastly 的特点是可以使用我们自己的证书,Cloudflare 虽然也有这个服务,但是费用太高。如我上文提到的,我们现在已经具备使用 HTTP/2 推送的能力。但是,Fastly 就不支持 DNS,这个在 Cloudflare 那里是支持的。现在我们需要自己解决 DNS 的问题了。可能最有意思的就是这些来回的折腾吧?
全局 DNS
- 我们自己的 DNS 服务器(备用)
- 的服务器(为了那些不需要 HTTPS 的跳转服务)
- Cloudflare DNS
- Route 53 DNS
- Google DNS
- Azure DNS
- 其他一些(测试时候使用)
REG_NAMECOM,
DnsProvider(R53,2),
DnsProvider(GOOGLECLOUD,2),
SPF,
TXT('@', 'google-site-verification=PgJFv7ljJQmUa7wupnJgoim3Lx22fbQzyhES7-Q9cv8'), // webmasters
A('@', ADDRESS24, FASTLY_ON),
'@'),
CNAME('chat',
A('meta', ADDRESS24, FASTLY_ON),
END)
测试
[[plan]]
label = "teststackoverflow_com"
url =
ips = ["28i"]
text = "<title>Test Stack Overflow Domain</title>"
tags = ["so"]
[[plan]]
label = "tls_teststackoverflow_com"
url =
ips = ["28"]
text = "<title>Test Stack Overflow Domain</title>"
tags = ["so"]
应用层准备
换一句话说:我们的 Q&A 全站都是跑在同一个服务器上的同一个进程,而用户对此没有感知。我们在九台服务器上每一台跑一个进程,只是为了发布版本和冗余的问题。
全局登录
整个项目中有一些看起来可以独立出来(事实上也是),不过也同属于整个大 HTTPS 迁移中的一部分。登录就是其中一个项目。我首先来说说这个,因为这比别它变化都要早上线。
客户端的代码不复杂,基本上长这样:
$.post('/users/login/universal/request', function (data, text, req) {
$.each(data, function (arrayId, group) {
var url = '//' + group.Host + '/users/login/universal.gif?authToken=' +
encodeURIComponent(group.Token) + '&nonce=' + encodeURIComponent(group.Nonce);
$(function () { $('#footer').append('</img>'); });
});
}, 'json');
但是要做到这点,我们必须上升到账号级别的认证(之前是用户级别)、改变读取 cookie 的方式、改变这些 meta 站的登录工作方式,同时还要将这一新的变动整合到其它应用中。比如说,Careers(现在拆成了 Talent 和 Jobs)用的是另一份代码库。我们需要让这些应用读取相应的 cookies,然后通过 API 调用 Q&A 应用来获取账户。我们部署了一个 NuGet 库来减少重复代码。底线是:你在一个地方登录,就在所有域名都登录。不弹框,不重载页面。
本地 HTTPS 开发
要想做得更好的话,本地环境应该尽量与开发和生产环境保持一致。幸好我们用的是 IIS,这件事情还简单的。我们使用一个工具来设置开发者环境,这个工具的名字叫「本地开发设置」——单纯吧?它可以安装工具(Visual Studio、git、SSMS 等)、服务(SQL Server、Redis、Elasticsearch)、仓库、数据库、网站以及一些其它东西。做好了基本的工具设置之后,我们要做的只是添加 SSL/TLS 证书。主要的思路如下:
Websites = @(
@{
Directory = "StackOverflow";
Site =
Aliases =
Databases = "Sites.Database", "Local.StackExchange.Meta", "Local.Area51", "Local.Area51.Meta";
Certificate = $true;
},
@{
Directory = "StackExchange.Website";
Site =
Databases = "Sites.Database", "Local.StackExchange", "Local.StackExchange.Meta", "Local.Area51.Meta";
Certificate = $true;
}
)
「Nick 你就扯吧,我们能拿到从 Google 拿到 referer 啊!」确实。但是这是因为他们主动选择这一行为。如果你看一下 Google 的搜索页面,你可以看到这样的 <meta>
指令:
<meta content="origin" id="mref" name="referrer">
这也就是为什么你可以取到 referer。
好的,我们已经设置好了,现在该做些什么呢?