61-Java-分布式开发框架Dubbo-- 笔记

笔记内容来源与黑马程序员教学视频


文章目录

  • 61-Java-分布式开发框架Dubbo-- 笔记
  • 分布式开发框架Dubbo
    • 笔记中涉及资源:
  • 一、分布式系统中的相关概念
    • ①:大型互联网项目架构目标
    • ②:集群和分布式
    • ③:架构演进
  • 二、Dubbo 概述
    • ①:概述
    • ②:Dubbo架构
  • 三、Dubbo 快速入门
    • ①:Zookeeper安装
    • Zookeeper安装笔记: [https://mp.csdn.net/mp_blog/creation/success/127578406](https://mp.csdn.net/mp_blog/creation/success/127578406)
    • ②:Dubbo快速入门
      • 1. 创建工程和模块
      • 2. 导入依赖和Tomcat插件
      • 3. 代码实现
      • 4. 启动项目
    • ③:使用Dubbo实现
      • 1. 导入dubbo相关依赖(所有模块)
      • 2.代码实现(dubbo-service)
      • 3.代码实现(dubbo-web)
    • ④:启动测试
    • ⑤:优化代码
      • 1.创建公共包(dubbo-interface)
      • 2.创建UserService接口
      • 3.重启测试访问
  • 四、Dubbo 高级特性
    • ①:dubbo-admin管理平台安装
      • dubbo-admin管理平台安装与简单使用笔记:https://mp.csdn.net/mp_blog/creation/success/127585897
    • ②:dubbo-序列化
      • 1. 创建一个新的模块(dubbo_pojo)
      • 2. 代码实现
      • 3.启动服务测试
      • 4.实现Serializable接口
      • 5.启动服务在测试
    • ③:dubbo-地址缓存
    • ④:dubbo-超时
      • 1.模拟超时
      • 2.消费和生产都设置超时时间
    • ⑤:dubbo-重试
    • ⑥:dubbo-多版本
    • ⑦:dubbo-负载均衡
      • 1. 启动多台服务
      • 2.配置负载均衡策略
    • ⑧:dubbo-集群容错
      • 1. 容错模式
      • 2. 代码实现
    • ⑨:dubbo-服务降级
      • 1.配置降级策略

分布式开发框架Dubbo

笔记中涉及资源:

链接:https://pan.baidu.com/s/1lne-ZWLJR3OcZkg8EoZOhg
提取码:Coke

一、分布式系统中的相关概念

①:大型互联网项目架构目标

  • 大型互联网项目架构目标

    • 互联网项目特点:
      用户多
      流量大,并发高
      海量数据
      易受攻击
      功能繁琐
      变更快

    • 高性能:提供快速的访问体验。

  • 衡量网站的性能指标:

    • 响应时间:指执行一个请求从开始到最后收到响应数据所花费的总体时间。

    • 并发数:指系统同时能处理的请求数量。

      • 并发连接数:指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器连接的总TCP数量
      • 请求数:也称为QPS(Query Per Second) 指每秒多少请求.
        并发用户数:单位时间内有多少用户
    • 吞吐量:指单位时间内系统能处理的请求数量。

      • QPS:Query Per Second 每秒查询数。
      • TPS:Transactions Per Second 每秒事务数。
      • 一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
      • 一个页面的一次访问,只会形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,就会有多个QPS

QPS >= 并发连接数 >= TPS

②:集群和分布式





③:架构演进







二、Dubbo 概述

①:概述

  • Dubbo是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架。
  • 致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
  • 官网:http://dubbo.apache.org

②:Dubbo架构

三、Dubbo 快速入门

①:Zookeeper安装

Zookeeper安装笔记: https://mp.csdn.net/mp_blog/creation/success/127578406

②:Dubbo快速入门

1. 创建工程和模块

  • 环境Jdk1.8 使用本地Maven 不要忘记

2. 导入依赖和Tomcat插件

  • dubbo-web 和dubbo-service 中导入以下依赖

    • dubbo-web 打包方式为war包
    • dubbo-service 不需要导入Tomcat插件
 <properties><spring.version>5.1.9.RELEASE</spring.version><dubbo.version>2.7.4.1</dubbo.version><zookeeper.version>4.0.0</zookeeper.version><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!-- servlet3.0规范的坐标 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!--spring的坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>
<!--            <version>${spring.version}</version>--><version>5.1.9.RELEASE</version></dependency><!--springmvc的坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId>
<!--            <version>${spring.version}</version>--><version>5.1.9.RELEASE</version></dependency><!--日志--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.21</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.21</version></dependency><!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId>
<!--            <version>${dubbo.version}</version>--><version>2.7.4.1</version></dependency><!--ZooKeeper客户端实现 --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId>
<!--            <version>${zookeeper.version}</version>--><version>4.0.0</version></dependency><!--ZooKeeper客户端实现 --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId>
<!--            <version>${zookeeper.version}</version>--><version>4.0.0</version></dependency><!--公共接口模块-->
<!--        <dependency>-->
<!--            <groupId>com.it</groupId>-->
<!--            <artifactId>dubbo-interface</artifactId>-->
<!--            <version>1.0-SNAPSHOT</version>-->
<!--        </dependency>--></dependencies><build><plugins><!--tomcat插件--><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>8000</port><path>/</path></configuration></plugin></plugins></build>

3. 代码实现

1.UserService

public interface UserService {public String sayHello();
}

2.UserServiceImpl

@Service
public class UserServiceImpl implements UserService {@Overridepublic String sayHello() {return "Hello Dubbo~~";}
}

3. dubbo-service --→ applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.it.service"/></beans>

4. dubbo-service --→ log4j.properties

# DEBUG < INFO < WARN < ERROR < FATAL
# Global logging configuration
log4j.rootLogger=info, stdout,file
# My logging configuration...
#log4j.logger.com.tocersoft.school=DEBUG
#log4j.logger.net.sf.hibernate.cache=debug
## Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%nlog4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=../logs/iask.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}  %l  %m%n

5.dubbo-web --→ web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"><!-- spring --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:spring/applicationContext*.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- Springmvc -->     <servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/springmvc.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping></web-app>

6.dubbo-web 引入service依赖

 <dependency><groupId>com.it</groupId><artifactId>dubbo-service</artifactId><version>1.0-SNAPSHOT</version></dependency>

7.UserController

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/sayHello")public String sayHello() {return userService.sayHello();}
}

8.springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--    开启注解--><mvc:annotation-driven/><context:component-scan base-package="com.it.controller"/>
</beans>

4. 启动项目

  • 因为web模块中引入了service模块 所有先将service模块安装一下
  • 启动web模块
  • 访问

③:使用Dubbo实现

1. 导入dubbo相关依赖(所有模块)

<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId>
<!--            <version>${dubbo.version}</version>--><version>2.7.4.1</version>
</dependency><!--ZooKeeper客户端实现 -->
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId>
<!--            <version>${zookeeper.version}</version>--><version>4.0.0</version>
</dependency><!--ZooKeeper客户端实现 -->
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId>
<!--            <version>${zookeeper.version}</version>--><version>4.0.0</version>
</dependency>

2.代码实现(dubbo-service)

1.dubbo-service中引入Tomcat插件 端口为8223

 <build><plugins><!--tomcat插件--><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>8223</port><path>/</path></configuration></plugin></plugins></build>

2.修改打包方式 为war包启动

3.@Servie注解换成Dubbo中的

4.添加配置信息

<!--  dubbo的配置-->
<!-- 1. 配置项目的名称(唯一)--><dubbo:application name="dubbo-service"/>
<!-- 2. 配置注册中心地址(如NAcos ZooKeeper)--><dubbo:registry address="zookeeper://192.168.100.200:2181"/>
<!-- 3. 配置dubbo包扫描--><dubbo:annotation package="com.it.service.impl"/>

5.添加web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"><!-- spring --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:spring/applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
</web-app>

3.代码实现(dubbo-web)

1.注释掉web模块中对service模块的依赖

2. 删除web.xml中的Spring的配置信息

3.使用dubbo中的@Reference注解远程注入

4.创建UserService

package com.it.service;public interface UserService {public String sayHello();
}

5.springmvc.xml中添加以下配置

<!--  dubbo的配置-->
<!-- 1. 配置项目的名称(唯一)-->
<dubbo:application name="dubbo-web"/>
<!-- 2. 配置注册中心地址(如NAcos ZooKeeper)-->
<dubbo:registry address="zookeeper://192.168.100.200:2181"/>
<!-- 3. 配置dubbo包扫描-->
<dubbo:annotation package="com.it.controller"/>

④:启动测试

  • 启动两个模块(访问)
  • 修改任何一个服务的端口
 <!-- 1. 配置项目的名称(唯一)--><dubbo:application name="dubbo-web"><dubbo:parameter key="qos.port" value="33333"/></dubbo:application>

  • 重新启动服务测试

⑤:优化代码

1.创建公共包(dubbo-interface)

2.创建UserService接口

1.在dubbo-interface模块中创建接口

2.删除dubbo-service和dubbo-web中的UserService接口

3.dubbo-service和dubbo-web中引入dubbo-interface模块依赖

<dependency><groupId>com.it</groupId><artifactId>dubbo-interface</artifactId><version>1.0-SNAPSHOT</version>
</dependency>

3.重启测试访问

  • dubbo-interface模块进行install安装

四、Dubbo 高级特性

①:dubbo-admin管理平台安装

dubbo-admin管理平台安装与简单使用笔记:https://mp.csdn.net/mp_blog/creation/success/127585897

②:dubbo-序列化

1. 创建一个新的模块(dubbo_pojo)

  • 在模块中创建一个User实体类
public class User {private int id;private String name;private String gender;private int age;// 提供有参 无参 get set 方法
}

2. 代码实现

1.dubbo-web 中定义Controller方法

    /*** 根据id查询用户* @return*/@RequestMapping("id")public User getUserById(id){return userService.getById(id);}

2.dubbo-interface中引入dubbo-pojo包的依赖,并创建User接口方法

<dependency><groupId>com.it</groupId><artifactId>dubbo_pojo</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
 /*** 根据id查询用户* @param id* @return*/User getById(int id);

3.在dubbo-service中完成接口的具体实现

    @Overridepublic User getById(int id) {return  new User(id,"zhangsan","男",20);}

3.启动服务测试

1.dubbo-interface和dubbo_pojo模块进行install安装
重启service和web 进行访问

4.实现Serializable接口

5.启动服务在测试

1.dubbo-interface和dubbo_pojo模块进行install安装
重启service和web 进行访问

③:dubbo-地址缓存

1.测试停止zookeeper在进行访问

  • 可以,因为dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。
  • 当服务提供者地址发生变化时,注册中心会通知服务消费者。

④:dubbo-超时


1.模拟超时

1.在生产者中添加睡眠程序,模拟超时

@Service(timeout = 3000, retries = 0)
public class UserServiceImpl implements UserService {private final ExecutorService fixedThreadPool = newFixedThreadPool(1);@Overridepublic User getById(int id){// 开一个新的线程打印数字fixedThreadPool.execute(UserServiceImpl::run);// 使主程序睡眠try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}return  new User(id,"zhangsan","男",20);}private static void run() {int time = 0;while (true) {System.out.println("time = " + time);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}time++;}}.....
}

2.访问测试

2.消费和生产都设置超时时间

  • 为了更好的观察将开线程打印数字的代码放到controller中
    private final ExecutorService fixedThreadPool = newFixedThreadPool(1);/*** 根据id查询用户* @return*/@RequestMapping("id")public User getUserById(int id){// 开一个新的线程打印数字fixedThreadPool.execute(() -> {int time = 0;while (true) {System.out.println("time = " + time);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}time++;}});return userService.getById(id);}
  • 结果一秒之后就报错了
  • 建议:超时时间(timeout)配置在服务的提供方

⑤:dubbo-重试



⑥:dubbo-多版本

1.在复制一个接口实现类(模拟多个版本)

2.测试1

3.测试2

⑦:dubbo-负载均衡

负载均衡策略(4种):

  • Random :按权重随机,默认值。按权重设置随机概率。
  • RoundRobin :按权重轮询。
  • LeastActive:最少活跃调用数,相同活跃数的随机。
  • ConsistentHash:一致性 Hash,相同参数的请求总是发到同一提供者。

1. 启动多台服务

1.第一次启动

2.第二次启动需要修改端口号



3.按照同样的方式修改在启动一次

4.启动成功后查看dubbo-admin

2.配置负载均衡策略

1.测试 重启web服务 访问测试

⑧:dubbo-集群容错

1. 容错模式

集群容错模式:

  • Failover Cluster:失败重试。默认值。当出现失败,重试其它服务器 ,默认重试2次,使用 retries 配置。一般用于读操作
  • Failfast Cluster :快速失败,只发起一次调用,失败立即报错。通常用于写操作。
  • Failsafe Cluster :失败安全,出现异常时,直接忽略。返回一个空结果。
  • Failback Cluster :失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
  • Forking Cluster :并行调用多个服务器,只要一个成功即返回。
  • Broadcast Cluster :广播调用所有提供者,逐个调用,任意一台报错则报错。

2. 代码实现

1.分别启动3太service服务

2.调用端配置 集群容错模式

3.启动web服务进行测试

4.在进行一次访问测试

⑨:dubbo-服务降级


服务降级方式:

  • mock=force:return null 表示消费方对该服务的方法调用都直
    接返回u川值,不发起远程调用。用来屏蔽不重要服务不可用
    时对调用方的影响。

  • mock=fail:return null 表示消费方对该服务的方法调用在失败
    后,再返回u川值,不抛异常。用来容忍不重要服务不稳定时
    对调用方的影响。

  • 具体使用可参考官方文档:https://dubbo.apache.org/zh/docs3-v2/java-sdk/advanced-features-and-usage/service/service-downgrade/

1.配置降级策略

1.@Reference(mock=“fail:return null” ) // 失败后返回null 不抛异常

2.测试

61-Java-分布式开发框架Dubbo相关推荐

  1. 分布式开发框架Dubbo

    一.分布式系统中的相关概念 1.大型互联网项目架构目标 1)互联网项目特点: 用户多.流量大,并发高.海量数据.易受攻击.功能繁琐.变更快 2)目标 高性能:提供快速的访问体验. 高可用:网站服务一直 ...

  2. NutzWk 5.2.0 重磅发布,Java 微服务分布式开发框架

    NutzWk 5.2.0 更新内容: 运维中心重磅功能完成,可在线上传jar包.编辑配置文件.关闭实例进程.启动新实例进程.动态修改日志等级.查看服务器资源占用情况等,支持分布式部署: 文件上传由本地 ...

  3. Java分布式 RPC 框架性能大比拼,Dubbo真的最差吗?

    点击上方"搜云库技术团队",选择"设为星标" 回复"1024"或"面试题"获取学习资料 Dubbo 是阿里巴巴公司开源的 ...

  4. Java分布式 RPC 框架性能大比拼,Dubbo最差?

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RP ...

  5. Java 分布式 RPC 框架性能大比拼,Dubbo 排第几?

    Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 不过,略有遗憾的是,据说在淘宝内部,du ...

  6. 阿里java架构师面试128题含答案:分布式架构+Dubbo+多线程+Redis

    一.Java基础和高级 1.String类为什么是final的. 2.HashMap的源码,实现原理,底层结构. 3.反射中,Class.forName和classloader的区别 4.sessio ...

  7. JAVA分布式篇3——Dubbo

    JAVA分布式篇3--Dubbo 1.架构演变 1.1.单应用架构 当网站流量很小时,只需要一个应用,将所有的功能部署到一起(所有业务都放在一个tomcat 里),从而减少部署节点和成本 用于简化 增 ...

  8. B2C商城项目源码,基于Java开发的高可用分布式B2C商城系统,Java+Spring MVC+Dubbo+Zookeeper+MySQL+Redis+FastDFS+Nginx+Solr

    目录 前言 B2C商城-AIYOU 一.项目总体架构 二.系统软硬件设施总体规划 1.系统服务规划 2.应用服务规划 3.应用系统域名规划 三.系统运行环境构建 四.项目数据库创建 五.项目拉取 六. ...

  9. Java分布式二手房项目尚好房第三课 利用Dubbo拆分微服务

    Java分布式二手房项目尚好房:Apache Dubbo介绍 一.分布式RPC框架Apache Dubbo 1.软件架构的演进过程 软件架构的发展经历了由单体架构.垂直架构.SOA架构到微服务架构的演 ...

最新文章

  1. 第三天·HTML常用标签
  2. Delphi 2010 refactor / refactoring 重构不能使用的原因以及解决
  3. 为什么一些机器学习模型需要对数据进行归一化?
  4. NFS客户端、服务器协商读写粒度(rsize、wsize)流程 【转】
  5. python 怎么查看变量的数据类型
  6. python宏替换_简单的宏替换
  7. k3 cloud 文件服务器搭建,k3cloud服务器推荐配置
  8. linux向脚本传递参数,Linux 使用位置变量向脚本传递参数
  9. AirPlay、AirTunes 移植开发
  10. Spring集成JPA提示Not an managed type
  11. Git commit (amend)
  12. 沙特阿拉伯重新开放对于持有美国、英国和申根签证旅行者落地签
  13. NRZ 对比 PAM4 调制技术
  14. 钉钉 for Mac(企业通讯软件)
  15. 两台Sawyer机械臂在rviz中的运动规划
  16. 选股器用计算机测试利润,ROE+市盈率选股 上周使用计算公式:总得分=营业净利润率+资产负债率+市盈率,来筛选股票。 因为笔者不会计算机编程,在计算历年平均值的时候... - 雪球...
  17. 华人占大半壁江山!CVPR 2021 目标检测论文大盘点(65篇论文)
  18. 福禄克用CFP-Q-ADD实现光纤一级认证测试
  19. Messager说明
  20. php可以考研,一位学长的考研经历-写给犹豫在考研边缘的你-转的

热门文章

  1. ③计算机病毒实验实验报告
  2. newmultipartentity php,使用MultipartEntity图片上传
  3. 为空口“定制”L2:MAC、RLC、PDCP和SDAP子层之MAC
  4. 网站UI设计应具有的8大品质和特点--摘自《众妙之门--网站UI设计之道》
  5. 威猛的 90 后,不等领导下班就先走,《2021 年轻人下班报告》公布
  6. 谷歌时代结束 - Google中国名称已经改回
  7. 【山外笔记-计算机网络·第7版】第13章:计算机网络名词缩写汇总
  8. 前端大事记之几件大事
  9. input如何设置默认值
  10. 什么是UTM参数?这些你知道吗