mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-17 08:46:40 +08:00
322 lines
23 KiB
HTML
322 lines
23 KiB
HTML
<!DOCTYPE html>
|
||
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||
<link rel="icon" href="/static/favicon.png">
|
||
<title>15 如何向面试官证明你做的系统是高可用的?.md.html</title>
|
||
<!-- Spectre.css framework -->
|
||
<link rel="stylesheet" href="/static/index.css">
|
||
<!-- theme css & js -->
|
||
<meta name="generator" content="Hexo 4.2.0">
|
||
</head>
|
||
<body>
|
||
<div class="book-container">
|
||
<div class="book-sidebar">
|
||
<div class="book-brand">
|
||
<a href="/">
|
||
<img src="/static/favicon.png">
|
||
<span>技术文章摘抄</span>
|
||
</a>
|
||
</div>
|
||
<div class="book-menu uncollapsible">
|
||
<ul class="uncollapsible">
|
||
<li><a href="/" class="current-tab">首页</a></li>
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
<li><a href="../">上一级</a></li>
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/00 开篇词 中高级研发面试,逃不开架构设计这一环.md.html">00 开篇词 中高级研发面试,逃不开架构设计这一环.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/01 研发工程师想提升面试竞争力,该具备这三个技术认知.md.html">01 研发工程师想提升面试竞争力,该具备这三个技术认知.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/02 研发工程师如何用架构师视角回答架构设计方案?.md.html">02 研发工程师如何用架构师视角回答架构设计方案?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/03 面试官如何考察与 CAP 有关的分布式理论?.md.html">03 面试官如何考察与 CAP 有关的分布式理论?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/04 亿级商品存储下,如何深度回答分布式系统的原理性问题?.md.html">04 亿级商品存储下,如何深度回答分布式系统的原理性问题?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/05 海量并发场景下,如何回答分布式事务一致性问题?.md.html">05 海量并发场景下,如何回答分布式事务一致性问题?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/06 分布式系统中,如何回答锁的实现原理?.md.html">06 分布式系统中,如何回答锁的实现原理?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/07 RPC:如何在面试中展现出“造轮子”的能力?.md.html">07 RPC:如何在面试中展现出“造轮子”的能力?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/08 MQ:如何回答消息队列的丢失、重复与积压问题.md.html">08 MQ:如何回答消息队列的丢失、重复与积压问题.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/08 案例串联 如何让系统抗住双十一的预约抢购活动?.md.html">08 案例串联 如何让系统抗住双十一的预约抢购活动?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/09 如何回答 MySQL 的索引原理与优化问题?.md.html">09 如何回答 MySQL 的索引原理与优化问题?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/10 如何回答 MySQL 的事务隔离级别和锁的机制?.md.html">10 如何回答 MySQL 的事务隔离级别和锁的机制?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/11 读多写少:MySQL 如何优化数据查询方案?.md.html">11 读多写少:MySQL 如何优化数据查询方案?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/12 写多读少:MySQL 如何优化数据存储方案?.md.html">12 写多读少:MySQL 如何优化数据存储方案?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/13 缓存原理:应对面试你要掌握 Redis 哪些原理?.md.html">13 缓存原理:应对面试你要掌握 Redis 哪些原理?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/14 缓存策略:面试中如何回答缓存穿透、雪崩等问题?.md.html">14 缓存策略:面试中如何回答缓存穿透、雪崩等问题?.md.html</a>
|
||
</li>
|
||
<li>
|
||
<a class="current-tab" href="/专栏/架构设计面试精讲/15 如何向面试官证明你做的系统是高可用的?.md.html">15 如何向面试官证明你做的系统是高可用的?.md.html</a>
|
||
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/16 如何从架构师角度回答系统容错、降级等高可用问题?.md.html">16 如何从架构师角度回答系统容错、降级等高可用问题?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/17 如何向面试官证明你做的系统是高性能的?.md.html">17 如何向面试官证明你做的系统是高性能的?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/18 如何从架构师角度回答怎么应对千万级流量的问题?.md.html">18 如何从架构师角度回答怎么应对千万级流量的问题?.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/19 彩蛋 互联网架构设计面试,你需要掌握的知识体系.md.html">19 彩蛋 互联网架构设计面试,你需要掌握的知识体系.md.html</a>
|
||
</li>
|
||
<li>
|
||
|
||
<a href="/专栏/架构设计面试精讲/结束语 程序员的道、术、势.md.html">结束语 程序员的道、术、势.md.html</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||
<div class="sidebar-toggle-inner"></div>
|
||
</div>
|
||
<script>
|
||
function add_inner() {
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
inner.classList.add('show')
|
||
}
|
||
function remove_inner() {
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
inner.classList.remove('show')
|
||
}
|
||
function sidebar_toggle() {
|
||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let content = document.querySelector('.off-canvas-content')
|
||
if (sidebar_toggle.classList.contains('extend')) { // show
|
||
sidebar_toggle.classList.remove('extend')
|
||
sidebar.classList.remove('hide')
|
||
content.classList.remove('extend')
|
||
} else { // hide
|
||
sidebar_toggle.classList.add('extend')
|
||
sidebar.classList.add('hide')
|
||
content.classList.add('extend')
|
||
}
|
||
}
|
||
function open_sidebar() {
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
sidebar.classList.add('show')
|
||
overlay.classList.add('show')
|
||
}
|
||
function hide_canvas() {
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
sidebar.classList.remove('show')
|
||
overlay.classList.remove('show')
|
||
}
|
||
</script>
|
||
<div class="off-canvas-content">
|
||
<div class="columns">
|
||
<div class="column col-12 col-lg-12">
|
||
<div class="book-navbar">
|
||
<!-- For Responsive Layout -->
|
||
<header class="navbar">
|
||
<section class="navbar-section">
|
||
<a onclick="open_sidebar()">
|
||
<i class="icon icon-menu"></i>
|
||
</a>
|
||
</section>
|
||
</header>
|
||
</div>
|
||
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;">
|
||
<div class="book-post">
|
||
<p id="tip" align="center"></p>
|
||
<div><h1>15 如何向面试官证明你做的系统是高可用的?</h1>
|
||
<p>我们已经用了五个模块分别讲了架构原理、分布式技术、中间件、数据库,以及缓存,这些都是面试中必考的技术领域和技术点,又因为我们处在大数据和互联网时代,所以高可用高性能这些非功能性需求的考察,也是你需要了解的,所以在最后一个模块,我会带你打卡高可用高性能的架构设计面试实战。</p>
|
||
<p>我在 01 讲中说过,高级研发工程师和架构师的区别不在于掌握了多少技术,而在于你所能驾驭系统的边界。这其实也反映了一个研发工程师的成长历程,起初独立负责一个功能,然后负责一个系统模块,再负责一个系统,最后负责多个系统或业务条线。</p>
|
||
<p>但是不管你在哪个阶段,有一个问题你肯定逃不开:怎么证明自己负责的系统是高可用的?因为任何一个系统架构初衷,最基本的诉求是要保证系统的稳定性和可用性,然后才是基于高流量的场景下,保证系统的并发承载能力。</p>
|
||
<h3>案例背景</h3>
|
||
<p>一般来讲,面试官在考察你系统架构的设计能力时,经常会让你说一下你在上一家公司是怎么设计系统架构的,以此了解你的设计能力和思路。</p>
|
||
<p>而你在讲解架构设计时,也是在向面试官逐步证明,自己负责的系统是如何做到高可用的。这会涉及一个公认的论证——SLA。服务等级协议(Service-Level Agreement,SLA)最根本的形式是协议双方(服务提供者和用户)签订的一个合约或协议。这个合约规范了双方的商务关系或部分商务关系。简单点儿说,你可以认为 SLA 是服务可用性一个重要衡量指标。</p>
|
||
<p>业界一般用几个 9 的 SLA 服务等级来衡量互联网应用的可用性。比如京东的可用性是 4 个 9(京东的服务 99.99% 可用):京东的服务要保证在所有的运行时间里只有 0.01% 不可用,也就是说一年大概有 52.6 分钟不可用,这个 99.99% 就叫作系统的可用性指标。</p>
|
||
<p>52.6 分钟是怎么计算出来的呢?</p>
|
||
<p><img src="assets/CioPOWAs3d-AU1jSAAAJ1V9HKdE826.png" alt="Drawing 0.png" /></p>
|
||
<p>SLA 的计算公式</p>
|
||
<p>从公式中可以看出, SLA 等于 4 个 9,也就是可用时长达到了 99.99% ,不可用时长则为是0.01%,一年是 365 天, 8760 个小时,一年的不可用时长就是 52.6 分钟,那么:</p>
|
||
<ul>
|
||
<li>SLA 等于 3 个 9,就相当于一年不可用时长等于 526 分钟;</li>
|
||
<li>SLA 等于 5 个 9,就相当于一年不可用时长等于 5.26 分钟。</li>
|
||
</ul>
|
||
<p>可以发现,用 SLA 等于 4 个9 作为参照物,少个 9 相当于小数点往后移一位,多个 9 相当于小数点往前移一位(我把系统可用性指标总结成一张表格)。</p>
|
||
<p><img src="assets/Cgp9HWAuYU2ANzYsAADiIW0-zW8205.png" alt="1.png" /></p>
|
||
<p>系统可用性指标</p>
|
||
<p><strong>那么问题就来了:</strong> 既然 SLA 是服务可用性的一个衡量指标,那么你在面试时,怎么设置这个指标的阈值才合理呢?</p>
|
||
<ul>
|
||
<li>一般来讲,2 个 9 表示系统基本可用,年度不可用时间小于 88 小时。</li>
|
||
<li>3 个 9 是较高可用,年度不可用时间小于 9 个小时。</li>
|
||
<li>4 个 9 是具有自动恢复能力的高可用,年度不可用时间小于 53 分钟。</li>
|
||
<li>5 个 9 指极高的可用性,年度不可用时间小于 5 分钟。</li>
|
||
</ul>
|
||
<p>在电商平台中(比如淘宝、京东、拼多多),系统可用性大多是 4 个 9。那么你在回答时,一要了解 SLA 的概念,N 个 9 代表什么含义,更要清楚互联网对于 SLA 的主流设定阈值。</p>
|
||
<p>讲到这儿,你可能会觉得:那我清楚了 SLA 的概念,然后也了解了 SLA 的主流设定阈值,当面试官问我“你们的系统高可用做得怎么样”时,我回答系统做到了 N 个 9 是不是就可以了?</p>
|
||
<h3>案例分析</h3>
|
||
<p>给你 10 秒钟的时间思考一下,当面试官听到你按照时间指标度量系统可用性,会不会满意?</p>
|
||
<p>要知道,任何一家互联网公司,都有流量的低峰期和高峰期,你在低峰期停机 1 分钟和高峰期停机 1 分钟,对业务影响的结果完全不同。<strong>如果认识不到这一点,面试官很容易认为你很业余,并没有实践经验。</strong></p>
|
||
<p>所以,仅凭理论指标在有些情况下是不能满足实际需求的,那有没有更加科学的度量方式呢?答案就是基于一段时间(比如 1 年)的停机影响的请求量占比,进行评估,公式如下:</p>
|
||
<p><img src="assets/CioPOWAs3f-ARcGTAAAKDhhS0CU196.png" alt="Drawing 2.png" /></p>
|
||
<p>这样一来,你就可以评估,业务在高峰期停机和在低峰期停机分别造成多少的损失了。<strong>所以,如果你再回答系统高可用指标的时候,我建议你可以遵循这样的套路:先摆明度量的两种方式,“N 个 9” 和 “影响请求量占比”,然后再结合实际业务场景表明第二种方式的科学性。</strong></p>
|
||
<p>总的来说,作为候选人,要立足业务价值去回答问题,不是仅停留于技术概念的堆砌,这才能体现你的思考。</p>
|
||
<p>当然了,以上的内容基本可以满足你应聘初中级研发工程师的需求,如果你要面试高级研发工程师或者是架构师,你还要有一个思路的闭环。<strong>为了方便你的记忆,我把这个思路总结为:“可评估”“可监控”“可保证”。</strong></p>
|
||
<p>所以,当你向面试官证明系统高可用时,其实是在回答这样几个问题:</p>
|
||
<ul>
|
||
<li>如何评估系统高可用?</li>
|
||
<li>如何监控系统高可用?</li>
|
||
<li>如何保证系统高可用?</li>
|
||
</ul>
|
||
<p>接下来,我们继续学习“如何监控系统高可用”至于“如何保证系统高可用”我将在下一讲中为你解答。</p>
|
||
<h3>案例解答</h3>
|
||
<p>我们以设计一个保证系统服务 SLA 等于 4 个 9 的监控报警体系为例。<strong>监控系统包括三个部分:基础设施监控报警、系统应用监控报警,以及存储服务监控报警。</strong> 接下来,我就围绕这三个最核心的框架带你设计一个监控系统,并基于监控系统的设计,让你了解到系统哪些环节会影响系统整体的可用性,从而在面试中对系统高可用设计有更加清晰的掌握。</p>
|
||
<ul>
|
||
<li><strong>基础设施监控</strong></li>
|
||
</ul>
|
||
<p>基础设施监控由三个部分组成:监控报警指标、监控工具以及报警策略。</p>
|
||
<p><strong>监控报警指标分为两种类型。</strong></p>
|
||
<ol>
|
||
<li>系统要素指标:主要有 CPU、内存,和磁盘。</li>
|
||
<li>网络要素指标:主要有带宽、网络 I/O、CDN、DNS、安全策略、和负载策略。</li>
|
||
</ol>
|
||
<p>为什么我们要监控这些指标?因为它们是判断系统的基础环境是否为高可用的重要核心指标。</p>
|
||
<p><img src="assets/Cgp9HWAuYWyATkxVAABau7vw5jQ035.png" alt="2.png" /></p>
|
||
<p>监控报警指标</p>
|
||
<p><strong>监控工具常用的有</strong>ZABBIX(Alexei Vladishev 开源的监控系统,覆盖市场最多的老牌监控系统,资料很多)、Open-Falcon(小米开源的监控系统,小米、滴滴、美团等公司内部都在用)、Prometheus(SoundCloud 开源监控系统,对 K8S 的监控支持更好)。这些工具基本都能监控所有系统的 CPU、内存、磁盘、网络带宽、网络 I/O 等基础关键指标,再结合一些运营商提供的监控平台,就可以覆盖整个基础设施监控。</p>
|
||
<p><strong>监控报警策略一般由时间维度</strong>、<strong>报警级别</strong>、<strong>阈值设定三部分组成</strong>。</p>
|
||
<p><img src="assets/CioPOWAuYX-APgb5AABCnrQ8zLc613.png" alt="3.png" /></p>
|
||
<p>监控报警策略</p>
|
||
<p>为了方便你理解监控报警策略,我举个例子。假设系统的监控指标有CPU、内存和磁盘,监控的时间维度是分钟级,监控的阈值设置为占比。那么你可以定义出如下的监控报警策略:</p>
|
||
<p><img src="assets/CioPOWAuYZKAaViEAACdg3MBCqE160.png" alt="4.png" /></p>
|
||
<p>为了第一时间监测到指标的健康度,报警级别可以分为紧急、重要,以及一般。当 CPU、内存,以及磁盘使用率这三项指标的每分钟采集的指标达到 90% 使用率时,就触发“紧急报警”;达到 80% 触发“重要报警”;70% 触发“一般报警”。</p>
|
||
<ul>
|
||
<li><strong>系统应用监控</strong></li>
|
||
</ul>
|
||
<p>业务状态监控报警,关注点在于系统自身状态的监控报警。和基础设施监控一样,它也是由监控指标,监控工具,报警策略组成,不同的是,系统应用监控报警的核心监控指标主要有流量、耗时、错误、心跳、客户端数、连接数等 6 个核心指标,监控工具有 CAT、SkyWalking、Pinpoint、Zipkin 等。</p>
|
||
<p><img src="assets/Cgp9HWAuYaSAOg3MAABlYMloePk508.png" alt="5.png" /></p>
|
||
<p>系统应用监控</p>
|
||
<ul>
|
||
<li><strong>存储服务监控</strong></li>
|
||
</ul>
|
||
<p>一般来讲,常用的第三方存储有 DB、ES、Redis、MQ 等。</p>
|
||
<p>对于存储服务的监控,除了基础指标监控之外,还有一些比如集群节点、分片信息、存储数据信息等相关特有存储指标的监控。</p>
|
||
<p>对于存储服务监的内容细节,我这里就不再一一介绍,在面试中,你只需要基于监控系统的三个核心组成部分(基础设施监控、系统应用监控、存储服务监控)来回答问题即可,比如,你可以回答:我为了确保系统的健康可靠,设计了一套监控体系,用于在生产环境对系统的可用性进行监控,具体的指标细节可以结合业务场景进行裁剪,比如你们是游戏领域,所以很关注流量和客户端连接数。</p>
|
||
<p>总的来说,<strong>让面试官认可你有一个全局的监控视角,比掌握很多监控指标更为重要。</strong></p>
|
||
<p>当然,很多互联网公司都很重视系统服务稳定性的工作,因为服务的稳定性直接影响用户的体验和口碑,线上服务稳定性是研发工程师必须要重点关注的问题。所以当你回答完上述问题后,有的面试官为了考察候选人的责任意识,一般还会追问:“如果线上出现告警,你作为核心研发,该怎么做呢?”</p>
|
||
<p>对于线上故障,要有应急响应机制,我总结以下几点供你参考:</p>
|
||
<p><img src="assets/CioPOWAuYbuAaS3EAAFIiTdJNEg195.png" alt="6.png" /></p>
|
||
<h3>总结</h3>
|
||
<p>我们来回顾一下今天的重点内容。</p>
|
||
<p>为了在面试中更好地回答怎么评估系统高可用,我们讲解了 SLA 的概念以及评估方法,并得出“以停机时间影响的系统请求量作为评估指标”比较科学。</p>
|
||
<p>为了确保线上服务的稳定运行,在设计监控系统时,要考虑三个核心点,基础设施监控、系统应用监控,以及存储服务监控。</p>
|
||
<p>另外,我强调了故障处理是研发工程师在进阶过程中必须经历的,而故障处理能力也是面试官最为看重的能力之一,所以对于怎么处理各类故障,你要形成一套体系化的知识框架。</p>
|
||
<p>为了方便你的记忆,我将今天的内容总结如下。</p>
|
||
<p><img src="assets/CioPOWAs3luAbbhpAAEjKaU8JLg460.png" alt="Drawing 7.png" /></p>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style="float: left">
|
||
<a href="/专栏/架构设计面试精讲/14 缓存策略:面试中如何回答缓存穿透、雪崩等问题?.md.html">上一页</a>
|
||
</div>
|
||
<div style="float: right">
|
||
<a href="/专栏/架构设计面试精讲/16 如何从架构师角度回答系统容错、降级等高可用问题?.md.html">下一页</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||
</div>
|
||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"709979238be93cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||
</body>
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||
<script>
|
||
window.dataLayer = window.dataLayer || [];
|
||
function gtag() {
|
||
dataLayer.push(arguments);
|
||
}
|
||
gtag('js', new Date());
|
||
gtag('config', 'G-NPSEEVD756');
|
||
var path = window.location.pathname
|
||
var cookie = getCookie("lastPath");
|
||
console.log(path)
|
||
if (path.replace("/", "") === "") {
|
||
if (cookie.replace("/", "") !== "") {
|
||
console.log(cookie)
|
||
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||
}
|
||
} else {
|
||
setCookie("lastPath", path)
|
||
}
|
||
function setCookie(cname, cvalue) {
|
||
var d = new Date();
|
||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||
var expires = "expires=" + d.toGMTString();
|
||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||
}
|
||
function getCookie(cname) {
|
||
var name = cname + "=";
|
||
var ca = document.cookie.split(';');
|
||
for (var i = 0; i < ca.length; i++) {
|
||
var c = ca[i].trim();
|
||
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||
}
|
||
return "";
|
||
}
|
||
</script>
|
||
</html>
|