欢迎大家来指出不好的地方
产品需求分析
- 用户账号体系不分中英文版本:在中文版本下注册的用户,在英文版本中也可以登录。
- 资讯类的数据做中英文两个版本:在中文版本中只有中文资讯,英文版本下只有英文资讯。
解决思路
- 一个数据库,用户表不分中英两张表。资讯类的表分中英两张表。
- 部署两个 rails 服务 (中英各一个),在 initialization 中使 model table_name 映射到相应版本的表名。
- 通过 Nginx 根据自定义的 http 头识别中英版本的请求,转发到相应的 rails 服务。
具体代码
- 例如创建两个版本的帖子表:cn_topics 与 en_topics
- 创建一个名为 Topic 的 Model
- 在 config/initializers 中 创建 map_multiversion_models.rb
MULTIVERSION_MODELS = %w(Topic).freeze
if ENV['CURRENT_LANG'] === 'CN'
current_lang_prefix = 'cn'
else
current_lang_prefix = 'en'
end
MULTIVERSION_MODELS.each do |t|
t.safe_constantize.table_name = "#{current_lang_prefix}#{t.underscore.pluralize}"
end
- nginx 的转发配置
upstream cn_production {
server 192.168.1.11:3000;
}
upstream en_production {
server 192.168.1.12:3000;
}
server {
location / {
if ($http_x_current_lang = 'cn') {
proxy_pass http://cn_production;
break;
}
if ($http_x_current_lang != 'cn') {
proxy_pass http://en_production;
break;
}
}
}
方案分析
- 数据隔离上通常有三种做法:数据库隔离、表隔离、元数据隔离。
- 数据库实例隔离不符合业务需求
- 元数据隔离方案会对正常业务代码造成污染,增加 lang 的字段来区别。
- 采用表隔离的方式,并用上面的解决方案
- 可以按正常的逻辑去写业务代码,避免了因为中英文版本问题对代码做兼容处理。
- 只需在环境变量中指定当前语言版本,即可同一套测试代码测试指定语言版本的业务代码