当我们说网络时,我们谈来什么(2)DNS

by admin on 2018年12月17日

优秀更新

咱俩一味想渲染通向叶子节点的基本点路径上的登时几乎单节点

DNS安全性

广大的DNS攻击模式DDos带富洪泛攻击,中间人抨击,发射攻击。

  • DDos:常见的同样种植攻击模式,通过向目的主机发送大量之分组,来让合法的请得无至相应,不过由于DNS的缓存服务,使得对于部分干净服务器或者是高于服务器的攻击取得好好地化解,固然到级服务器不可以正常应了,不过地面的DNS服务器遭到还来缓存,我我便不管需访问顶级服务器。

  • 中人抨击:通过对于DNS包的掣肘,重回制定的恶心地址,然后用用户引往恶意的源地址。该种形式可经向部分DNS服务器遭到发送伪造的记录,从而造成一个区域外之一些地点收到感染。

  • 放攻击:反射攻击不再是针对DNS服务器的抨击,而是指DNS的风味,将攻击对象主机的IP作为源地址发送大量的呼吁保管到DNS服务器,然后服务器的应就会指向本地,特别是于片告内容相比较应内容一经聊森之种,我们协调随便需好酷的流量就足以将目的主机淹没。

《总结机网络自顶向下》《TCP/IP详解》两本书结合着长自己在此之前的整治来好了本篇博客,未来要加快革新快了。网络了后,操作系统,编译原理的Flag也假使与进了。

浏览器工具

CPU 分析器火焰图表在寻觅你的应用程序的性问题时也克发挥功用。

每当做性能分析时,火焰图表会映现起各一样皮秒你的代码的 Javascript
堆栈的状态。在笔录的时刻,你就得适当地通晓任意时直接触实施之凡啊一个函数,它执行了多长时间,又是哪个调用了其。——
Mozilla

Firefox:
点击查看

Chrome:
点击查阅

感阅读,祝你顺利构建出高性能的 React 应用!

插播一修广告,6-18 野狗技术沙龙将吃 6 月 18 日 13:00 至 17:00
在都中关村创业大街 3W
咖啡举行,尽管你出趣味,你可点击这里打探详细音信获取报名办法。

DNS威逼污染

DNS威迫又称域名要挟,是凭在绑架的网范围外阻挡截域名解析的乞求,分析请求的域名,把对范围外的呼吁放行,否则重回假的IP地址或者什么还不做如求去响应,其功效固然是本着一定的纱不克影响或看的是假网址。国内对于一些外国的网站的墙之一手中,DNS胁制污染即便是一致栽,将有如墙掉的网站对一些不足看的地址,同时当前运营商也于提到一项相比较恶心的事务,也是为眼前众互联网商家于感冒的一个问题,运营商为牟利以有铺面之域名进行恫吓到外的店。相比显赫的几乎个胁迫事件都发在百度身上,最要命范围被域名胁迫祸害过之实在就是是百度,2010年百度域叫做吃伊朗网军恐吓了,整整两个刻钟用户达无失去百度,是百度创制以来最为惨重的服务器故障,据说间接损失直接跨越700万,直接损失再一次多。百度当时吧是单方面紧急启动备用登陆举办还原,一边痛骂威吓方。后来百度一向痛恨数据恐吓,以前360浏览器接纳百度时,会受360挑起流。(流氓之间互掐)当然现在多不行厂为起供公共DNS,来针对恶意网站举行阻拦,智能分析避免让威迫和广告的插。

研讨DNS污染,不得不提的凡DNSCrypt,其实现原理通过对DNS请求内容开展加密的不二法门来都行的缠绕了墙。

题目2:父子级之间强耦合

平凡而言,应用都要拓宽松耦合(组件对其他的组件知道之更少越好)。父组件应该尽量避免知晓其子组件的行事原理。这就允许你改变子组件的作为而并非叫父级知晓这一个变化(如果
PropsTypes
保持无换)。它还允许子组桩独立运行,而不用吃父级紧密的主宰该行为。

DNS解析流程

此地大家经过浏览器输入百度的IP地址来当实例。

  • 当大家在浏览器输入了网址,然后浏览器是时刻会调用操作系统提供的DNS转化服务
  • 率先是检测本地host文件,是否发缓存,而且未过,则应用
  • 设若非存,则会于为地方DNS服务器的殡葬了DNS解析请求,尽管地点DNS服务器缓存了百度的DNS记录,则用
  • 假使当地DNS服务器无该记录就转为根服务器请求,然后根服务器收到请求后,会回给当地服务器相应的一流域名DNS服务器地址。
  • www.baidu.com否条例,就回回解析com顶尖域名之服务器,然后本地服务器知道一级域的DNS服务器的地点后便晤面为该服务器发送解析呼吁,然后一流域服务器再次回到给当地DNS服务器百度的高贵服务器的IP地址。
  • 及齐,本地DNS服务器向百度的权威DNS服务器发起查询请求。就会拿走百度权威DNS服务器重回给本地服务器的百度服务器的IP地址。
  • 最后,本地DNS服务器会把百度服务器的IP地址再次回到给您的总计机,同时以及时漫漫记录缓存在本地DNS服务器。
    递归查询的图示
DNS query



Note:以上是通过递归的方式进行的查询操作,当然还存在其他的查询方式如仅仅的”递归“,通过对于报文头部字段的修改即可改变该种方式。

万一点轮廓

React 应用关键的性质问题在于多余的处理及零部件的 DOM
比对。为了避免这些性陷阱,你应该尽可能的在 shouldComponentUpdate
中返回 false

简单的讲,归咎于如下两接触:

  1. 加速 shouldComponentUpdate 的检查
  2. 简化 shouldComponentUpdate 的检查

DNS记录以及报文

DNS是一个分布式的数据库,那么数据库中记录了什么吗?DNS存储的笔录提供了自主机名到IP地址的映射,我们叫资源记录,而资源记录的格式则也一个四元组(Name,Value,Type,TTL),四元组中之各一个素代表什么吧?

  • TTL:记录之生存时间,决定了笔录由缓存中去除的大运。
  • Name/Value:值在Type
  • Type:
    • A:Name:主机名 Value:IP地址
    • NS:Name:域 Value:获取主机IP地址之大DNS服务器主机名
    • CNAME:Name:主机名 Value:规范主机名(bd.com
      dl.bd.com)用来简化记念
    • MX:Name:主机名 Value:邮件服务器的正式主机名
      DNS具备

dns_package

夫报文由12许节长的首部和4独长可变的字段组成。
标识字段由客户程序设置并出于服务器重回结果。客户程序通过其来规定响应和查询是否配合。

dns_header.

  • QR是1bit字段:0意味着查询报文,1意味应报文。
  • opcode是一个4bit字段:平时值为0(标准查询),其他价值也1(反向查询)和2(服务器状态请求)。
  • AA是1bit标志,表示“
    授权回答(authoritativeanswer)”。该名服务器是授权给该域的。
  • TC是1bit字段,表示“可截断的(truncated)”。使用UDP时,它象征当对的到底长度超过512字节时,只回前512个字节。
  • RD是1bit字段代表“期望递归”。该比特能于一个查询中设置,
    并在响应中回到。这么些标志告诉名字服务器必须处理是查询,也号称一个递归查询。假若该位为
    0,且让请的名字服务器无一个授权对,它就回去一个能解答该查询的另外名字服务器列表,这名迭代查询。在后头的事例中,大家拿见到就点儿种档次查询的例证。
  • RA是1bit字段,表示“
    可用递归”。假使名字服务器匡助递归查询,则在应中将该比特设置也
    1。在末端的事例中唯独看出大多数名服务器都提供递归查询,除了少数根服务器。
  • 进而的3 bit字段必须为0。
  • rcode是一个4bit之回来码字段。平常的值为0(没有偏差)和3(名字差错)。名字差错唯有从一个授权名字服务器上回来,它表示以询问中制定的域名不设有。
  • 进而的4独16bit字段证实最后4独转移长字段被涵盖的条目数。对于查询报文,问题屡屡一般是1,而那他3码则全为0。类似地,对于答复报文,回答数至少是1,剩下的星星点点桩可以是0或非0。
dns\_header\_ask



查询名是要查找的名字,它是一个或多个标识符的序列。查询类型是我们上述所提到的type中的几个类型,查询类通常是1,指互联网地址。  
DNS报文中最后的三个字段,回答字段、授权字段和附加信息字段,均采用一种称为资源记录RR的相同格式。



dns\_header\_answer


前面几个字段和请求报文的字段的报文相同,这里不再详细介绍,着重介绍下后续几个字段。生存时间字段是客户程序保留该资源记录的秒数。资源记录通常的生存时间值为两天。资源数据长度说明资源数据的数量。该数据的格式依赖于类型字段的值。对于A类型资源数据是4字节的IP地址。

console.time

随即一个非常简单:

  1. 发端一个计时器
  2. 举办点啊
  3. 已计时器

一个于好之做法是运 Redux 中间件:

export default store => next => action => {
    console.time(action.type)

    // `next` 是一个函数,它接收 'action' 并把它发送到 ‘reducers' 进行处理
    // 这会导致你应有的一次重渲
    const result = next(action);

    // 渲染用了多久?
    console.timeEnd(action.type);

    return result;
};

于是之主意好记录你下之各级一个 action
和她引起的渲染所花费的工夫。你得赶快理解什么 action
渲染时间最好充裕,这样当你解决性能问题时常就足以打这里初阶。得到时刻价值还会帮而认清你所举行的性质优化是否见效了。

序言

未雨绸缪了挺遥远,以前好领悟不敷通彻的,这里自己参阅相关书籍,举办了以一个疏理。下篇更新TCP/UDP相关。进入正题,网域名称系统(英文:Domain
Name
System,缩写:DNS)是互联网的一样码服务。它看做将域名及IP地址相互映射的一个分布式数据库,可以使人头重复有益于地访问互联网。上述为来源维基百科对于DNS的叙说,通过简单概述,大家通晓了此系统是啊了。

  • 那么为什么要有这么个系统呢?互联网将大家每一个人连接起来,当大家想通过互联网开展联络,分享,那么首先我们需要一个标示来代表网中之各类一个人数,独一无二的,现实生活中大家下了身份证ID,网络中动用了IP地址,除了唯一性,其尚装有一个共性就是彼数字的排列在自然水准及拥有区域性,比如台湾总人口之身份证前几乎各或就是依然同之,同理甘肃之一对地段的IP地址的前头几乎员也是同一之。而我辈平日存受到见了丁是休相会说hi,371******909933的,我们谋面给名,为何,因为未待拿百度的IP记录下来,然后每便要物色东西的早晚,都要输入IP,有了其大家仅需要输入www.baidu.com即便足以了,卓殊好。
  • 这个系统为什么要做成分布式的呢?首先大家想到的一个策略是用IP和域名的对应存放于一个汇集之服务器上,然后当大家需要拜访转化的当儿,带在咱的域名发送网络要,然后系统依照我们的域名找到相互对应之IP,然后再次回IP地址为咱,大家通过IP地址
    DNS运行在UDP端口53。当前,对于各级顶尖域名长度的克是63只字符,域名总长度则免克过253个字符。
    论在此以前的讲述思路,大家事先打报文格式出手,然后于夫效率,解析流程,DNS污染威吓,DNS攻击来讲课DNS系统。

React 默认的渲染行为是咋样的?

大家来拘禁一下 React 是哪些渲染组件的。

DNS作用

DNS提供的劳动除外对域名及IP地址之转账之外,还提供了这多少个效率也?有以下几点

  • 主机别名
    有点主机名可能晤面具备多单主机别名,别名会更易于辨别,DNS则提供了一如既往种植服务,用来展开以别名到主机名之投,然后找到主机的IP地址并再次来到。
  • 邮件服务器列表
    电子邮件选拔得举办DNS请求,对提供的邮件服务器别名展开辨析,然后拿走主机的科班主机名及IP地址。
  • 负载均衡
    设想一个题材,尽管大家的一个域名对应一个IP地址,一个IP地址为即对承诺同等台主机,当用户量异常好之时光,我们在访问的进程中,则会用服务器淹没,由此会将域名对应一个IP地址集合,通过这一个集,每一遍重复起DNS请求,则会循环读博IP地址,然后下IP地址。

React 应用之要性能问题是什么?

  1. 组件中那多少个无更新 DOM 的冗余操作
  2. DOM 比对这一个永不更新的纸牌节点
    • 哪怕则 DOM 比对这一个不错并加快了 React ,但算成本是不容忽视的

默认行为

使您免告诉 React 别这样做,它就是会这样
(橘粉色 = 浪费的渲染)

嗯,不!大家富有的节点都受重复渲染了。

React 的每一个零件都爆发一个 shouldComponentUpdate(nextProps,
nextState)
函数。它的任务是当组件需要更新时重返 true
而组件不必更新时则重临 false 。返回 false 会导致组件的
render 函数不给调用。React 总是默认在 shouldComponentUpdate
中返回 true,固然你没有展现地定义一个 shouldComponentUpdate
函数。

// 默认行为
shouldComponentUpdate(nextProps, nextState) {
    return true;
}

当即就象征在默认境况下,你每便换代您的顶层级的
props,整个应用之各一个组件都碰面渲染。这是一个至关首要的属性问题。

工具

上述列出来的有规则和技艺都是经使用性能测量工具发现的。使用工具得以扶持你发觉而的采取之现实性性质问题所在。

特种状况:函数

  1. 假使得以吧,尽量避免传递函数。相反,让子组件自由的 dispatch
    动作。这还来只附加的便宜虽将作业逻辑移出组件。
  2. shouldComponetUpdate
    中忽略函数检查。这样不是颇美,因我们无清楚函数的价值是否变动了。
  3. 创办一个 data -> function 的不可变绑定。你得于
    componentWillReceiveProps 函数惨遭拿其存到 state
    中失。这样尽管非汇合当各样一样次 render
    时得到新的援。这些法子极其笨重,因为若得维护及翻新一个函数列表。
  4. 始建一个有着无可争执 this
    绑定的中级组件。这吗不够赏心悦目,因为您于层级中引入了一个冗余层。
  5. 其他其他你可以想到的、可以防止每趟 render
    调用时成立一个初函数的不二法门。

方案4 的示例

// 引入另外一层 'ListItem'
<List>
    <ListItem> // 你可以在这里创建正确的 this 绑定
        <Item />
    </ListItem>
</List>

class ListItem extends React.Component {

    // 这样总能得到正确的 this 绑定,因为它绑定在了实例上
    // 感谢 es7!
    const callback = () => {
        dispatch(doSomething());
    }

    render() {
        return <Item callback={this.callback} item={this.props.item} />
    }
}

加速 shouldComponentUpdate 检查

不错图景下我们无期望于 shouldComponentUpdate
中做老抵检查,因为就特别高昂,尤其是于广泛和所有大的数据结构的时候。

class Item extends React.component {
    shouldComponentUpdate(nextProps) {
      // 这很昂贵
      return isDeepEqual(this.props, nextProps);
    }
    // ...
}

一个替情势是苟对象的值发生了变通,就改成目标的援

const newValue = {
    ...oldValue
    // 在这里做你想要的修改
};

// 快速检查 —— 只要检查引用
newValue === oldValue; // false

// 如果你愿意也可以用 Object.assign 语法
const newValue2 = Object.assign({}, oldValue);

newValue2 === oldValue; // false

于 Redux reducer 中动用这些技术:

// 在这个 Redux reducer 中,我们将改变一个 item 的 description
export default (state, action) {

    if(action.type === 'ITEM_DESCRIPTION_UPDATE') {

        const { itemId, description } = action;

        const items = state.items.map(item => {
            // action 和这个 item 无关 —— 我们可以不作修改直接返回这个 item
            if(item.id !== itemId) {
              return item;
            }

            // 我们想改变这个 item
            // 这会保留原本 item 的值,但
            // 会返回一个更新过 description 的新对象
            return {
              ...item,
              description
            };
        });

        return {
          ...state,
          items
        };
    }

    return state;
}

若果你下那法子,这若一味待以 shouldComponentUpdate
函数吃作引用检查

// 超级快 —— 你所做的只是检查引用!
shouldComponentUpdate(nextProps) {
    return isObjectEqual(this.props, nextProps);
}

isObjectEqual 的一个贯彻示例

const isObjectEqual = (obj1, obj2) => {
    if(!isObject(obj1) || !isObject(obj2)) {
        return false;
    }

    // 引用是否相同
    if(obj1 === obj2) {
        return true;
    }

    // 它们包含的键名是否一致?
    const item1Keys = Object.keys(obj1).sort();
    const item2Keys = Object.keys(obj2).sort();

    if(!isArrayEqual(item1Keys, item2Keys)) {
        return false;
    }

    // 属性所对应的每一个对象是否具有相同的引用?
    return item2Keys.every(key => {
        const value = obj1[key];
        const nextValue = obj2[key];

        if(value === nextValue) {
            return true;
        }

        // 数组例外,再检查一个层级的深度
        return Array.isArray(value) && 
            Array.isArray(nextValue) && 
            isArrayEqual(value, nextValue);
    });
};

const isArrayEqual = (array1 = [], array2 = []) => {
    if(array1 === array2) {
        return true;
    }

    // 检查一个层级深度
    return array1.length === array2.length &&
        array1.every((item, index) => item === array2[index]);
};

简化 shouldComponentUpdate 检查

先行押一个复杂shouldComponentUpdate 示例

// 关注分离的数据结构(标准化数据)
const state = {
    items: [
        {
            id: 5,
            description: 'some really cool item'
        }
    ]

    // 表示用户与系统交互的对象
    interaction: {
        selectedId: 5
    }
};

若是这么社团而的多少,会教在 shouldComponentUpdate
中开展自我批评变得困难

import React, { Component, PropTypes } from 'react'

class List extends Component {

    propTypes = {
        items: PropTypes.array.isRequired,
        iteraction: PropTypes.object.isRequired
    }

    shouldComponentUpdate (nextProps) {
        // items 中的元素是否发生了改变?
        if(!isArrayEqual(this.props.items, nextProps.items)) {
            return true;
        }

        // 从这里开始事情会变的很恐怖

        // 如果 interaction 没有变化,那可以返回 false (真棒!)
        if(isObjectEqual(this.props.interaction, nextProps.interaction)) {
            return false;
        }

        // 如果代码运行到这里,我们知道:
        //    1. items 没有变化
        //    2. interaction 变了
        // 我们需要 interaction 的变化是否与我们相干

        const wasItemSelected = this.props.items.any(item => {
            return item.id === this.props.interaction.selectedId
        })
        const isItemSelected = nextProps.items.any(item => {
            return item.id === nextProps.interaction.selectedId
        })

        // 如果发生了改变就返回 true
        // 如果没有发生变化就返回 false
        return wasItemSelected !== isItemSelected;
    }

    render() {
        <div>
            {this.props.items.map(item => {
                const isSelected = this.props.interaction.selectedId === item.id;
                return (<Item item={item} isSelected={isSelected} />);
            })}
        </div>
    }
}

React.perf

此家伙的思路与 console.time 是平等的,只不过用底是 React
的性工具:

  1. Perf.start()
  2. do stuff
  3. Perf.stop()

Redux 中间件示例:

import Perf from 'react-addons-perf';

export default store => next => action => {
    const key = `performance:${action.type}`;
    Perf.start();

    // 拿到新的 state 重渲应用
    const result = next(action);
    Perf.stop();

    console.group(key);
    console.info('wasted');
    Perf.printWasted();
    // 你可以在这里打印任何你感兴趣的 Perf 测量值

    console.groupEnd(key);
    return result;
};

console.time 方法类似,它亦可给您瞧您各类一个 action
的性能目标。更多关于 React 性能 addon
的音请点击这里

提出改变

我们记挂翻新一部分多少。这多少个改变仅同一个纸牌节点相关

免责注解!

章中之言传身教是用 React + Redux
写的。如若您用的是另外数额流库,原理是相通的而落实会见不同。

当小说被自我没用 immutability (不可变)库,只是有的平凡的 es6 和一些
es7。有些东西用不可变数据库要简明一点,不过自己不准备在那里探讨即同样片情节。

问题1:shouldComponentUpdate 体积庞大

君得看一个非凡简单的数对应之 shouldComponentUpdate
即大而繁杂。这是盖它需要明白数码的构造与它中的干。shouldComponentUpdate
函数的复杂度和体积仅就你的数据结构增长。这很容易以致个别碰错:

  1. 于非应当回到 false 的时刻回来 false(应用显示错误的状态)
  2. 于非应当归 true 的上回来 true(引发性能问题)

怎么而于事情变得这么复杂?你只有想让那多少个检查变得简单一点,以至于你一直不怕无需考虑她。

咱们怎么着得到理想的改进?

尽可能的在 shouldComponentUpdate 中返回 false

简单来讲:

  1. 加速 shouldComponentUpdate 的检查
  2. 简化 shouldComponentUpdate 的检查

釜底抽薪问题之策略

  1. 避以组件中创造动态的 props

革新您的数据模型,那样您即便可直接拿 props 传下

  1. 把动态 props 转化成为饱全齐(===)的品种传下去

eg:

  • boolean
  • number
  • string

const bool1 = true;
const bool2 = true;

bool1 === bool2; // true

const string1 = 'hello';
const string2 = 'hello';

string1 === string2; // true

若是你实际要传递动态目标,那固然将她当作字符串传下去,再当子级举行解构

render() {
    const {items} = this.props;

    <div>
        {items.map(item => {
            // 每次获得新引用
            const bad = {
                id: item.id,
                type: item.type
            };

            // 相同的值可以满足严格的全等 '==='
            const good = `${item.id}::${item.type}`;

            return <Item identifier={good} />
        })}
    </div>
}

伊始化渲染

每当初叶化渲染时,我们要渲染整个应用
(青色 = 已渲染节点)

列一个节点都让渲染 —— 这生赞扬!现在我们的施用显示了俺们的起状态。

解决办法:压平你的多寡

经过压平(合并)你的数据结构,你得又利用异常简单的援检查来拘禁是不是来啊爆发了别。

const state = {
    items: [
        {
            id: 5,
            description: 'some really cool item',

            // interaction 现在存在于 item 的内部
            interaction: {
                isSelected: true
            }
        }
    }
};

这么社团而的多少驱动以 shouldComponentUpdate 中做检查变得简单

import React, {Component, PropTypes} from 'react'

class List extends Component {

    propTypes = {
        items: PropTypes.array.isRequired
    }

    shouldComponentUpdate(nextProps) {
        // so easy,麻麻再也不用担心我的更新检查了
        return isObjectEqual(this.props, nextProps);
    }

    render() {
        <div>
            {this.props.items.map(item => {

                return (
                <Item item={item}
                    isSelected={item.interaction.isSelected} />)
            })}
        </div>
    }
}

倘使你想要更新 interaction 你虽变更整个对象的援

// redux reducer
export default (state, action) => {

    if(action.type === 'ITEM_SELECT') {

        const { itemId } = action;

        const items = state.items.map(item => {
            if(item.id !== itemId) {
                return item;
            }

            // 改变整个对象的引用
            return {
                ...item,
                interaction: {
                    isSelected: true
                }
            }
        })

        return {
            ...state,
            items
        };
    }

    return state;
};

误区:引用检查和动态 props

一个创设动态 props 的例证

class Foo extends React.Component {
    render() {
        const {items} = this.props;

        // 这个对象每次都有一个新的引用
        const newData = { hello: 'world' };

        return <Item name={name} data={newData} />
    }
}

class Item extends React.Component {

    // 即便前后两个对象的值相同,检查也总会返回true,因为 `data` 每次都会得到一个新的引用
    shouldComponentUpdate(nextProps) {
        return isObjectEqual(this.props, nextProps);
    }
}

平凡大家不会晤在组件中创制一个初的 props 把她污染下去
。不过,这在循环中尤为广阔

class List exntends React.Component {
    render() {
        const {items} = this.props;

        <div>
            {items.map((item, index) => {
                // 这个对象每次都会获得一个新引用
                const newData = {
                    hello: 'world',
                    isFirst: index === 0
                };

                return <Item name={name} data={newData} />
            })}
        </div>
    }
}

即当成立函数时杀宽泛

import myActionCreator from './my-action-creator';

class List extends React.Component {
    render() {
        const {items, dispatch} = this.props;

        <div>
            {items.map(item => {
                // 这个函数的引用每次都会变
                const callback = () => {
                    dispatch(myActionCreator(item));
                }

                return <Item name={name} onUpdate={callback} />
            })}
        </div>
    }
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图