時(shí)間:2023-02-26 12:24:01 | 來源:建站知識(shí)
時(shí)間:2023-02-26 12:24:01 來源:建站知識(shí)
cname記錄是什么?他存在的意義是什么?:背景通過請(qǐng)求頭傳遞租戶標(biāo)識(shí)是目前比較常見的方式,常見做法是在頁面的登錄頁添加一個(gè)租戶選擇框,前端根據(jù)選擇的租戶標(biāo)識(shí)在請(qǐng)求工具的攔截器統(tǒng)一帶給后端。
該方式存在不足:
1.第三方對(duì)接支持不好,當(dāng)該租戶的接口需要給第三方做回調(diào)的時(shí)候就不能支持了,比如微信公眾號(hào)回調(diào)、支付回調(diào)等。
2.對(duì)租戶使用體驗(yàn)不好,需要租戶自己在頁面手動(dòng)選擇使用的租戶,也不方便對(duì)登錄頁進(jìn)行定制化設(shè)計(jì)。
一般作為通過請(qǐng)求頭傳遞的一個(gè)補(bǔ)充,在不支持回調(diào)的情況下額外使用。
不建議使用,會(huì)和業(yè)務(wù)參數(shù)混合在一起,不方便區(qū)分。以上為常見的租戶標(biāo)識(shí)傳遞傳遞方案,通過請(qǐng)求頭 + url 參數(shù)配合使用。今天小白給大家分享一個(gè)不一樣的方案,通過域名 + CNAME 的方式傳遞租戶標(biāo)識(shí)。
*.tenant.xiaobai.com
映射到具體的ip
,這樣就可以直接通過{租戶標(biāo)識(shí)}.tenant.xiaobai.com
訪問到服務(wù)器,但是租戶標(biāo)識(shí)往往都是一些沒有具體意義的一串字符,比如7e97639a733942c8ba530c5d54857a07
,加上大部分的租戶都想使用自己的域名,需要增加租戶自定義域名,這時(shí)候通過租戶的域名 CNAME 解析到{租戶標(biāo)識(shí)}.tenant.xiaobai.com
DomainTenantParseUtils
/** * 解析域名租戶 * * @param domain 當(dāng)前訪問域名 * @param tenantRootDomain 租戶的根域名(可以是二級(jí)或者三級(jí)域名) * @return 租戶標(biāo)識(shí) */ @Nullable public static String parseDomainTenant(@NonNull String domain, @NonNull String tenantRootDomain) { // ip不解析 if (IpUtils.isIP(domain)) { return null; } String resolvingResult; // 當(dāng)前訪問域名在租戶根域名下解析結(jié)果為當(dāng)前訪問域名 if (domain.endsWith(tenantRootDomain)) { resolvingResult = domain; } else { resolvingResult = getResolvingResult(domain, Type.CNAME); } // 解析結(jié)果為空直接返回 if (Objects.isNull(resolvingResult)) { return null; } // 解析結(jié)果不在租戶根域名下 if (!resolvingResult.endsWith(tenantRootDomain)) { return null; } String[] rootDomainArray = tenantRootDomain.split("//."); String[] resolvingResultArray = resolvingResult.split("//."); // 取租戶根域名的下一級(jí) if (resolvingResultArray.length > rootDomainArray.length) { return resolvingResultArray[resolvingResultArray.length - (rootDomainArray.length + 1)]; } return null; } /** * 獲取域名解析結(jié)果 * * @param domain 域名 * @param type 類型 A記錄 或者 CNAME * @see Type */ @Nullable public static String getResolvingResult(String domain, int type) { Resolver resolver; Lookup lookup; try { // 設(shè)置DNS服務(wù)器,這里使用常用的114.114.114.114 // TODO 這里也可做成配置化 resolver = new SimpleResolver("114.114.114.114"); lookup = new Lookup(domain, type); } catch (TextParseException | UnknownHostException e) { throw new RuntimeException("域名解析異常"); } lookup.setResolver(resolver); org.xbill.DNS.Cache cache = new org.xbill.DNS.Cache(); lookup.setCache(cache); lookup.run(); if (lookup.getResult() == Lookup.SUCCESSFUL) { String[] results = cache.toString().split("//n"); for (String result : results) { String rule = "(?<=//[)(.+?)(?=.])"; Pattern pattern = Pattern.compile(rule); Matcher matcher = pattern.matcher(result); if (matcher.find()) { return matcher.group(); } } } return null; }
TenantParseFilter
@Slf4j@RequiredArgsConstructorpublic class TenantParseFilter extends OncePerRequestFilter { private final TenantProperties tenantProperties; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestServerName = request.getServerName(); String tenant = DomainTenantParseUtils.parseDomainTenant(requestServerName, tenantProperties.getRootDomain()); if (!Objects.isNull(tenant)) { // 獲取到了租戶標(biāo)識(shí) if (log.isDebugEnabled()) { log.debug("域名解析到的租戶標(biāo)識(shí):[{}]", tenant); } // TODO 寫自己的業(yè)務(wù)操作,比如設(shè)置租戶上下文傳遞 } filterChain.doFilter(request, response); }}
關(guān)鍵詞:意義,記錄
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。