为了账号安全,请及时绑定邮箱和手机立即绑定
3.2 电话和短信

Phone 设置项中可以模拟来电和短信:From:选择或输入电话号码;CALL DEVICE:点击来电;HOLD CALL:点击保持通话;END CALL:点击结束通话;SMS message:输入模拟消息的正文内容;SEND MESSAGE:点击发送短信。

3.1 模拟电话

模拟10086来电;gsm call 10086模拟接听来电;gsm accept 10086模拟挂断来电;gsm cancel 10086下面是完整会话示例。pt@Win10-Panda:~$ telnet localhost 5554Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.Android Console: Authentication requiredAndroid Console: type 'auth <auth_token>' to authenticateAndroid Console: you can find your <auth_token> in'C:\Users\panda\.emulator_console_auth_token'OKauth KeGgPVHDN7YifXfZAndroid Console: type 'help' for a list of commandsOKgsm call 10086OKgsm accept 10086OKgsm cancel 10086OK

2.5 电话模拟命令

命令说明gsm {call\accept\cancel\busy} phonenumber模拟电话的呼入、接听、挂断、繁忙。gsm {data\voice} statedata state 命令用于更改 GPRS 数据连接的状态,data voice state 则用于更改 GPRS 语音连接的状态。gsm hold将通话状态更改为 hold。只有在当前状态为 active 或 waiting 时,才能将通话状态更改为 hold。gsm list列出所有呼入电话和外拨电话及其通话状态。gsm status报告当前的 GSM 语音/数据连接状态。相关的值就是前述 voice 和 data 命令的值。

3.1 微信小程序 API

uni-app 的 API 与微信小程序 API 基本一致。掌握微信小程序 API 对后面的开发很有帮助。微信小程序 API 文档:https://developers.weixin.qq.com/miniprogram/dev/api/

3.4 电源

事件日志中包含屏幕电源状态,其中 0 表示屏幕关闭,1 表示屏幕打开,2 表示已锁屏。日志范例如下:grep screen_toggled bugreport-2015-10-18-16-52-22.txt10-18 15:05:04.383 992 992 I screen_toggled: 110-18 15:05:07.010 992 992 I screen_toggled: 010-18 15:23:15.063 992 992 I screen_toggled: 110-18 15:23:25.684 992 992 I screen_toggled: 010-18 15:36:31.623 992 992 I screen_toggled: 110-18 15:36:37.660 3283 3283 I screen_toggled: 2错误报告中还包含关于唤醒锁的统计信息,唤醒锁是应用开发者采用的一种机制,用于表明其应用需要设备保持开启状态。唤醒锁总时长统计信息仅跟踪唤醒锁实际负责使设备保持唤醒状态的时间,不包括屏幕处于开启状态的时间。此外,如果同时持有多个唤醒锁,系统会在它们之间分配唤醒锁时长。

2. 服务快速失败之服务熔断机制

服务熔断机制的服务快速失败所实现的目标,和我们在上述小节中所介绍的普通的服务快速失败所实现的目标相同,都是为了保证,在某一微服务发生故障时,不影响后续微服务的正常运行。雪崩效应产生原理在上述小节中,各位同学已经对什么是雪崩效应有所了解,如上图所示,我们所讲的服务熔断也是为了避免和解决雪崩现象的发生,只不过所采用的手段不同而已,那么接下来,就让我们来看一下基于服务熔断机制的服务快速失败的概念是什么吧。针对服务熔断机制,我们先来介绍什么是熔断?熔断这一名词,其实不是来源于计算机相关专业,而是来源于电子工程相关专业。熔断的核心是断路器,对于断路器来说,我们可以将断路器理解为一根保险丝,在日常生活中,当我们家庭用电超过负载时,保险丝就会迅速烧断,阻止由于电流过大而烧毁整个家庭电路。同样地,熔断我们也可以像保险丝那样理解,即在计算机相关领域中,由于中断上游的故障服务,而保全整体的服务的措施就被称为熔断,而实现中断上游的故障服务所采取的核心措施就是我们的断路器。服务熔断机制就是把这些概念都统一起来,然后封装到 Hystrix 中,且最终应用于我们的微服务项目中间,通过配置断路器,来保全我们整体的微服务项目,这就是 Hystrix 所提供的服务熔断机制。Tips: 1. 在实际工作中,我们需要灵活的去配置微服务项目中,各个领域的微服务所对应的断路器配置,包括间隔时间、持续时间等关键属性,切记不要凭感觉去配置; 2. Hystrix 本身所提供的服务熔断机制并不是很好用,往往需要我们在项目中集成其他的微服务服务中间件来一起集成使用,单独使用 Hystrix 服务熔断机制的项目很少见。

3. Zookeeper 的会话

Zookeeper 是一个 C/S 架构的服务,也就是 Client — Server 的形式。在我们使用 Zookeeper 时,都是使用 Zookeeper 的客户端向服务端发送请求,然后由服务端做出响应返回到客户端。在这个过程中,Zookeeper 的客户端需要与 Zookeeper 服务端建立连接,建立一个连接就是新建一个会话,那么会话的状态也就是 Zookeeper 客户端与 Zookeeper 服务端的连接状态。接下来我们从会话的结构开始进行讲解:

3.1 打包为微信小程序

注册微信小程序账号,获取到 AppID,我们后面配置的时候会用到。在 HBuilderX 工具栏,点击发行,选择小程序-微信。输入小程序名称和 AppID,单击发行就可以了。这样我们就会获得一个微信小程序的打包文件,接下来我们来发布微信小程序项目,打开微信小程序开发者工具,导入刚刚生成的微信小程序项目的打包文件,在微信小程序开发者工具中先测试一下,项目运行是否正常,项目测试没有问题后,点击右上角>>按钮,上传代码就可以发布微信小程序了,最后等待微信团队审核通过,别人就可以在线上访问到你的项目了。

1.2 没有验证通信方身份

通信双方无法确认对方的身份是否正确。案例1:本地电脑有木马,路由表被踹改,www.baidu.com 的域名被解析到另一台虚假的服务器,此时你在浏览器访问的百度就是黑客的另一个钓鱼网站,然后给你推送了很多虚假消息,此时客户端很难知情。案例2:路由表没问题,但是目标服务器被人黑了,处理不了请求,此时有其它服务冒充提供服务。案例3:某个资源只有特定用户有查询的权限,黑客通过伪造该客户端一样的请求来查询,服务端只是简单的根据入参判断,并无法知道对应客户端的真实性,于是消息很容易泄漏。

1. 数据转成电信号

数据转换成电信号还是比较简单的,将字符根据指定的编码转换成唯一的二进制编码,然后将二进制的 01 映射成高低电平就可以传输出去了。

3.3 会话层

通过传输层,建立了数据的传输通道。不同应用有自己不同的会话标识,所以传输过来的数据根据会话标识能够知道跟电脑的哪个应用在通信的。

2.3 数据库第三范式(3NF)

① 定义:第三范式(Third Normal Form)要求数据库表中的每个字段和主键都直接相关,不能间接相关。② 案例解释:还是以第一范式中的user_info表作为案例,如果要存储每个用户的省份和省会城市,我们可能会设计出下面这样一张表:用户编号(user_id)姓名(username)年龄(age)座机电话(fixed_phone)手机电话(cell_phone)省份(province)省会城市(city)1小明201008618010002000北京市北京市2小红211008718010002001黑龙江省哈尔滨市3小王221008818010002002贵州省贵阳市我们将用户编号(user_id)作为主键,则姓名、年龄、座机电话、手机电话都和"用户"这个主体强相关,和主键直接相关,而省份和省会城市则和"用户"这个主体是弱相关,和主键间接相关,并且存在依赖关系:用户编号 -> 姓名,姓名 -> 省份,省份 -> 省会城市,这样构建了用户编号 -> 省会城市的间接传递关系,这种关系会导致数据冗余,而且在执行删除/修改/增加操作的时候,会产生异常情况:删除所有"贵州省"下的用户信息(即user_id = 3的记录),"贵州省"和"贵阳市"的信息也被删除了(显然不合理,因为省份这个定义和省份下的人员记录并没有关系)。所以我们需要将user_info表拆分,我们通过省份构建数据关系,优化后的用户(user_info)表如下:用户编号(user_id)姓名(username)年龄(age)座机电话(fixed_phone)手机电话(cell_phone)省份(province)1小明201008618010002000北京市2小红211008718010002001黑龙江省3小王221008818010002002贵州省独立拆分出的省份(province)表如下:省份(province)省会城市(city)北京市北京市黑龙江省哈尔滨市贵州省贵阳市③ 范式优点:提高了表的独立性,降低数据存储冗余。

3.1 关于微服务监控平台

技巧 1如果我们的微服务监控平台没有任何数据,或者说,在打开微服务平台之后,各参数一直处于 loading 状态,这个时候,我们只需要在服务端调用任意一个服务接口即可,这样在微服务监控平台,我们就能看到被监控实例的参数了。技巧 2如果我们在访问 /actuator/hystrix.stream 路径时,系统找不到对应的路径,即报 404 异常,那么我们需要在对应项目的启动类中添加一个 Bean :@Beanpublic ServletRegistrationBean hystrixMetricsStreamServlet() { ServletRegistrationBean registration = new ServletRegistrationBean(new HystrixMetricsStreamServlet()); registration.addUrlMappings("/hystrix.stream"); return registration;}这样我们就能正常访问 /actuator/hystrix.stream 下的路径了。

4.2 豆瓣网

豆瓣网 (douban) 是一个社区网站,提供关于书籍、电影、音乐等作品的信息,还提供书影音推荐、线下同城活动、小组话题交流等多种服务功能。豆瓣网已经达拥有 300 万注册用户,访问量每天则超过两千万,是一个应用 Python 开发的非常成功的 Web 2.0 站点。豆瓣网的后端采用了 Quixote 框架,Quixote 框架是一个使用 Python 开发的轻量级 Web 框架。

4.1 主要泄漏信息

IP 地址,物理地址网站后台访问地址,密码信息家庭成员信息,电话信息生日(很多人的秘密是生日日期)公司信息,同事信息

2.2 Zookeeper 管理数据源配置

首先我们需要使用 Curator 客户端来连接 Zookeeper 服务端,并且在 Spring IOC 容器中拿到 dataSource,保存它的信息到节点的 data 中,然后对该节点开启监听,监听到节点更新事件后,获取节点新的信息,并更新数据源。在 curator 目录中新建 CuratorService 类:package cn.cdd.zookeeper.config.curator;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.framework.recipes.cache.*;import org.apache.curator.retry.RetryForever;import org.apache.zookeeper.data.Stat;import org.springframework.context.ConfigurableApplicationContext;import java.nio.charset.StandardCharsets;import java.sql.SQLException;public class CuratorService { private ConfigurableApplicationContext applicationContext; public CuratorService(ConfigurableApplicationContext applicationContext) { this.applicationContext = applicationContext; } private static final String DATASOURCE_NODE = "/imooc/datasource"; /** * 构建 CuratorFramework 客户端,并开启会话 * * @return CuratorFramework */ public CuratorFramework buildCuratorClient() { // 使用 CuratorFrameworkFactory 构建 CuratorFramework CuratorFramework client = CuratorFrameworkFactory.builder() // Zookeeper 地址 .connectString("127.0.0.1:2181") // 重连策略 .retryPolicy(new RetryForever(10000)) .build(); // 开启会话 client.start(); return client; } /** * 保存数据源信息到 Zookeeper * * @param client CuratorFramework * @throws Exception Exception */ public void saveDataSource(CuratorFramework client) throws Exception { // 在 Spring IOC 容器中获取 dataSource DruidDataSource dataSource = (DruidDataSource) applicationContext.getBean("dataSource"); JSONObject jsonObject = new JSONObject(); jsonObject.put("DriverClassName", dataSource.getDriverClassName()); jsonObject.put("Url", dataSource.getUrl()); jsonObject.put("Username", dataSource.getUsername()); jsonObject.put("Password", dataSource.getPassword()); // 检查 Zookeeper 服务端是否存在 DATASOURCE_NODE 节点 Stat stat = client.checkExists().forPath(DATASOURCE_NODE); // 不存在则创建,并保存信息 if (stat == null) { client.create().creatingParentsIfNeeded().forPath(DATASOURCE_NODE, jsonObject.toJSONString().getBytes()); } else { // 存在则修改信息 client.setData().forPath(DATASOURCE_NODE, jsonObject.toJSONString().getBytes()); } } /** * 开启监听 * * @param client CuratorFramework */ public void startMonitoring(CuratorFramework client) { // 构建 CuratorCache 实例 CuratorCache cache = CuratorCache.build(client, DATASOURCE_NODE); // 使用 Fluent 风格和 lambda 表达式来构建 CuratorCacheListener 的事件监听 CuratorCacheListener listener = CuratorCacheListener.builder() // 开启对节点更新事件的监听 .forChanges((oldNode, newNode) -> { // 从新节点获取数据 byte[] data = newNode.getData(); String config = new String(data, StandardCharsets.UTF_8); if (!config.isEmpty()) { JSONObject jsonObject = JSON.parseObject(config); try { loadDataSource(jsonObject); } catch (SQLException e) { e.printStackTrace(); } System.err.println(">>> 从配置中心更新数据源: " + config); } }) // 初始化 .forInitialized(() -> System.out.println(">>> CuratorCacheListener 初始化")) // 构建 .build(); // 注册 CuratorCacheListener 到 CuratorCache cache.listenable().addListener(listener); // CuratorCache 开启缓存 cache.start(); } /** * 加载数据源 * * @param jsonObject 配置信息 * @throws SQLException SQLException */ private void loadDataSource(JSONObject jsonObject) throws SQLException { // 在 Spring IOC 容器中获取 dataSource DruidDataSource dataSource = (DruidDataSource) applicationContext.getBean("dataSource"); // 已经初始化的数据源需要重新启动 if (dataSource.isInited()) { dataSource.restart(); } // 更新数据源配置 dataSource.setDriverClassName(jsonObject.getString("DriverClassName")); dataSource.setUrl(jsonObject.getString("Url")); dataSource.setUsername(jsonObject.getString("Username")); dataSource.setPassword(jsonObject.getString("Password")); // 数据源初始化 dataSource.init(); }}完成 CuratorService 类后,我们还需要 ConfigurableApplicationContext 来获取 IOC 容器中的 dataSource,我们可以在主类 ZookeeperConfigApplication 中获取:package cn.cdd.zookeeper.config;import cn.cdd.zookeeper.config.curator.CuratorService;import org.apache.curator.framework.CuratorFramework;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication@MapperScan(basePackages = "cn.cdd.zookeeper.config.dao")public class ZookeeperConfigApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(ZookeeperConfigApplication.class, args); try { // 使用 applicationContext 初始化 CuratorService CuratorService curatorService = new CuratorService(applicationContext); // 获取 Curator 客户端 CuratorFramework client = curatorService.buildCuratorClient(); // 保存数据源信息 curatorService.saveDataSource(client); // 开启监听 curatorService.startMonitoring(client); } catch (Exception e) { e.printStackTrace(); } }}接下来我们就可以开启 Zookeeper ,来对数据源的变化进行测试了。

1.1 客户端-服务端模型:

客户端,是指发起请求的一方。也就是浏览器,或者指爬虫程序。通过发起请求,来获取想要的网页。服务端,请求的响应端,是 web 服务端。web 服务,是一个虚拟意思上的机器的概念。可以是一个计算机集群,也可以是一个软件或者程序。客户端,通过发送一个请求给服务端,然后进行等待。服务端按照客户端的请求,返回客户端需要的数据。这个过程,我们称之为经典的客户端——服务端模型。

3.2 信号量隔离实现服务资源隔离

信号量隔离和线程池隔离的方式很相似,只不过把分配线程池的方式改为了分配信号量(至于什么是信号量,请同学们自行查阅)。在处理请求时,Hystrix 会分配一个信号量的阀值,当服务接收到一个请求后,信号量的阀值减 1 ,当请求处理完毕后,信号量的阀值加 1,当信号量的阀值减为 0 时,则不再接收请求,即该请求会被拒绝处理。@RequestMapping(value = "hello", method = RequestMethod.GET)@HystrixCommand(fallbackMethod="helloFail", commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"),@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "100")})@ResponseBodypublic String hello() throws InterruptedException { return "helloWorld";}public String helloFail() { return "helloFailed";}代码解释:第 4 行,通过指定 HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY 参数的值为 SEMAPHORE ,来声明该接口使用信号量隔离。第 7 行,通过指定 HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS 参数的值为 100 ,可以理解为设置信号量的阀值为 100 。通过添加上述配置参数,我们就可以通过信号量隔离的方式来实现服务资源隔离。Tips: 一定要合理设置信号量的阀值,不要随意设定,如果阀值设置过大,则请求不会停止,如果阀值设置过小,则不能满足业务需要。

2.3 电源状态命令

命令说明power display显示电池和充电器状态。power ac {on\off}将交流电充电状态设为 on 或 off。power status {unknown\charging\discharging\not-charging\full}按照说明更改电池状态。power present {true\false}设置电池存在状态。power health {unknown\good\overheat\dead\overvoltage\failure}设置电池运行状况。power capacity percent将电池剩余电量状态设为 0 到 100 之间的百分比。

2. 什么是服务监控平台

Hystrix 中的服务监控平台,就是对微服务项目进行监控的平台,包括服务运行的状态、服务有无宕机、服务异常信息监控等内容,为开发者和运维者提供了比较友好地界面支持,开发者和运维者可以直接通过观察服务平台界面,来判断具体微服务的状态信息,从而更好地对微服务进行控制。默认的 Hystrix 中间件已经为我们封装好了微服务监控平台,但是需要通过引入依赖的方式来使用它,接下来就让我们来看一下如何搭建该服务监控平台吧。

3. Hystrix 实现服务资源隔离

在 Hystrix 中,实现服务资源隔离有两种方式,分别是线程池隔离和信号量隔离。

2.1 微前端

微前端 尚处在发展时期,其核心概念和 微服务 相似。现阶段较为常用的微前端框架为 single-spa 和 qiankun,后者是基于前者实现的。该技术能做到 技术栈无关,即一个应用,能由多个不同技术的子应用构成,同时做到子应用的相互隔离,这里的隔离就可以选择采用 Web Components 实现。

3. Zookeeper 客户端

使用 Zookeeper 客户端连接 Zookeeper 服务,我们需要使用 ./zkCli.sh 命令:# 进入 bin 文件夹cd /usr/local/zookeeper/apache-zookeeper-3.6.1-bin/bin/# 连接命令./zkCli.sh # 连接时输出信息Connecting to localhost:2181...# 出现下面这一行时,表示我们连接成功[zk: localhost:2181(CONNECTED) 0] 这里我们就可以使用上一节学习过的命令来操作节点了,我们来测试一下:# 获取根节点的子节点ls /# 输出默认的子节点 zookeeper[zookeeper]# 创建根节点的子节点 imooccreate /imooc# 输出创建成功信息Created /imooc# 创建后再次获取根节点的子节点ls /# 输出两个子节点[imooc, zookeeper]# 我们可以给节点设置数据set /imooc wiki# 然后我们再获取 imooc 节点的数据get /imooc# 输出我们设置的信息wiki# 最后我们测试一下删除命令delete /imooc# 删除后再次获取根节点的子节点ls /# 输出子节点 zookeeper,imooc 节点被删除[zookeeper]# 退出 Zookeeper 客户端命令quit通过上面的学习,我们知道了如何部署单机模式的 Zookeeper 服务,以及如何通过 Zookeeper 客户端连接 Zookeeper 服务端,来对 Znode 节点进行操作。那么 Zookeeper 是如何为我们提供服务的呢,接下来我们就来了解单机模式下的 Zookeeper 的工作流程。

2. 需求分析

业务场景: 模拟微信聊天,每个客户端和服务端建立连接,并且可以实现点对点通信(单聊),点对多点通信(群聊)。设计思路: 我们要实现的是点(客户端)对点(客户端)的通讯,但是我们大部分情况下接触的业务都是客户端和服务端之间的通讯,客户端只需要知道服务端的 IP 地址和端口号即可发起通讯了,那么客户端和客户端应该怎么去设计呢?思考:难道是手机和手机之间建立通讯连接,互相发送消息吗?这种方案显然不是很好的方案,第一: 客户端和客户端之间通讯,首先需要确定对方的 IP 地址和端口号,显然不是很现实。第二: 即使有办法拿到对方的 IP 地址和端口号,那么每个点(客户端)既作为服务端还得作为客户端,无形之中增加了客户端的压力。其实,我们可以使用服务端作为中转站,由服务端主动往指定客户端推送消息,如果是这种模式的话,那么 Http 协议是无法支持的,Http 是无状态的,只能一请求一响应的模式,只能使用 TCP 协议去实现了。

2. 几种常用的客户端-服务器消息传递方式

http 最常用的协议,用于客户端主动向服务器发送请求,单向传递;ajax HTTP 的扩展版,底层还是 HTTP 协议,只不过客户端是无刷新的;comet 也是基于 HTTP 封装的,使用 HTTP 长连接的方式,原理大致是将 HTTP 的timeout 设置较长,服务器有数据变化时返回数据给客户端,同时断开连接,客户端处理完数据之后重新创建一个 HTTP 长连接,循环上述操作(这只是其中一种实现方式);websocket 这是 HTML5 中的新标准,基于 socket 的方式实现客户端与服务端双向通信,需要浏览器支持 HTML5;Adobe Flash Socket 这个也是使用 socket 的方式,需要浏览器支持 flash 才行,为了兼容老版本的浏览器;ActiveX object 只适用于 IE 浏览器;目前尚没有一种方式能兼容所有的浏览器,只能针对软件的目标客户人群做一定的兼容。sse 服务端单向推送。

1. 为什么需要Cookie和Session?

在 Web 程序中,对会话的跟踪是很一件非常重要的事情。通常,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能互不干扰。然而大部分的 Web 应用程序都是使用HTTP 协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。如果 Web 服务上没有这种的会话追踪功能,那么大部分网站都会陷入一片混乱。特别是对于电商网站而言,如果我添加一次购物车就需要登录一次确认身份,那对于用户体验而言是糟糕透的。会话(Session)跟踪是 Web 程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。正是有了 Cookie 和 Session 这样的会话跟踪技术,弥补了 HTTP 协议无状态的不足,才使得我们可以无差别的访问网站,即只需要一次登录,后续所有的操作通过 Cookie 或者 Session 便能自动识别为该用户,并维持在一个会话中。

3.1 四字命令介绍

这里我们列出常用的四字命令进行介绍:conf: 查询 Zookeeper 服务的配置信息。# 对客户端开放的端口,默认 2181clientPort=2181# 安全的客户端的端口secureClientPort=-1# 数据文件目录dataDir=/usr/local/zookeeper/apache-zookeeper-3.6.1-bin/data/version-2# 数据文件大小dataDirSize=67108880# 日志文件目录dataLogDir=/usr/local/zookeeper/apache-zookeeper-3.6.1-bin/data/log/version-2# 日志文件大小dataLogSize=914# 心跳检测间隔毫秒tickTime=2000# 最大客户端连接数maxClientCnxns=60# 最小的会话超时时间minSessionTimeout=4000# 最大的会话超时时间maxSessionTimeout=40000# 客户端端口列表备份日志clientPortListenBacklog=-1# 服务idserverId=0cons: 列出连接到 Zookeeper 服务的所有客户端的完整连接和会话详细信息。包括接收和发送的数据包数量、会话id、操作延迟、最后执行的操作等信息。/127.0.0.1:44244[0](queued=0,recved=1,sent=0)crst: 重置服务端的连接和会话统计信息。Connection stats reset.dump: 适用于 Leader 节点,列出未完成的请求和临时节点。envi: 列出服务器的环境信息。Environment:zookeeper.version=3.6.1--104dcb3e3fb464b30c5186d229e00af9f332524b, built on 04/21/2020 15:01 GMThost.name=fbbc740a6217java.version=1.8.0_261java.vendor=Oracle Corporationjava.home=/usr/local/java/jdk1.8.0_261/jrejava.class.path=/usr/local/java/jdk1.8.0_261/jre/libjava.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/libjava.io.tmpdir=/tmpjava.compiler=<NA>os.name=Linuxos.arch=amd64os.version=4.19.128-microsoft-standarduser.name=rootuser.home=/rootuser.dir=/usr/local/zookeeper/apache-zookeeper-3.6.1-binos.memory.free=142MBos.memory.max=889MBos.memory.total=192MBruok: 测试服务是否处于正确运行状态,如果正常返回 imok,否则返回空。srst: 重置服务的统计信息。srvr: 列出服务的详细信息。Zookeeper version: 3.6.1--104dcb3e3fb464b30c5186d229e00af9f332524b, built on 04/21/2020 15:01 GMTLatency min/avg/max: 0/0.0/0Received: 9Sent: 8Connections: 1Outstanding: 0Zxid: 0x2Mode: standaloneNode count: 5wchs: 列出服务的 Watcher 的简要信息。wchc: 按会话列出服务的 Watcher 的详细信息。wchp: 按路径列出服务带有 znode 列表的 Watcher 的详细信息。如果 Watcher 的数量多,会影响服务器性能,请谨慎使用。dirs: 以字节为单位显示快照和日志文件的总大小。datadir_size: 67108880logdir_size: 914

2. 传统 UDP 客户端和服务器建立过程

同样,我们展示了通过 C 语言 Socket API 编写 UDP 客户端和服务器程序的步骤,如下:图中的矩形方框都是 C 函数。对比 TCP 客户端、服务器的建立过程,我们发现 UDP 客户端可以调用 connect 函数,但是并不会去连接服务器,只是和本地接口做绑定;UDP 服务器是没有 listen 和 accept 调用的。对于 UDP 客户端来说,connect 函数的调用是可选的。接下来,我们就探讨一下如何用 Java 语言编写 UDP 客户端和服务器程序。

2. 服务资源隔离真实业务场景描述

业务场景描述有这样一个真实的业务场景:在某大厂的订单与支付模块,当有用户下了订单之后,需要在支付模块进行支付,支付动作完成之后,支付模块会将支付完成的结果返回给订单模块来通知用户,该订单是否支付成功,即商品是否已经成功购买了。在微服务分布式架构模式下,上述业务场景中出现了一种异常现象:当用户下了订单之后,在支付模块进行支付时,系统一直没有响应,无论是否成功支付,用户都收不到任何通知信息。程序员在排查对应的业务实现代码时,证实了业务实现代码没有问题,这就导致无法定位问题所在。最终经过几名同事一起排查,发现是订单模块与支付模块之间进行数据传输时,支付模块收到了订单模块传递过来的数据,但是由于服务器高压工作,导致支付模块始终无法处理该支付请求,这就导致系统一直没有响应。问题原因分析在解决问题之前,我们首先来分析一下这种问题产生的原因。在前面我们介绍什么是 Hystrix 资源隔离小节中,我为大家阐述了在我们的 Web 项目中,进程与线程之间的关系。我们知道,在一般情况下,一个 Web 项目中只有一个工作线程来负责处理用户调用的请求和服务,当该工作线程所负责的请求处理缓慢时,该线程就会一直处理当前的请求,导致后续请求只能等待处理,这就是我们说的雪崩现象。雪崩效应产生原理在微服务分布式架构模式下,由于我们没有对线程进行处理,至此在处理所有业务请求时,扔是只有一个工作线程,这就导致上述业务场出现了我们所说的雪崩现象,不过还好,这种雪崩现象比较轻微,只影响到了一个业务模块。很多时候,当我们的项目架构演变为基于微服务的分布式架构时,服务器也需要同步进行更新,有很多企业为了节约成本,则只更新很少数量的服务器,或者压根就不更新服务器,这就导致经常会出现由于服务器高压工作而出现的请求处理缓慢,或请求无法继续处理的情况。

4. 小结

本节我们讨论了如何利用第三方平台做我们系统的 OAuth2.0 认证中心,主要的知识点如下:Spring Security 实现了 OAuth2.0 客户端的常用功能,开发者可以轻松的将 Spring Boot 应用作为 OAuth2.0 客户端集成到安全体系中;在使用第三方作为 OAuth2.0 认证服务器时,首先要在第三方平台上完成应用注册,并获取到 Client ID 和 Client Secret 两个重要参数;使用第三方 OAuth2.0 认证源,可以简化系统开发中的关于认证的操作,并且可以更轻易的实现单点登录;使用第三方 OAuth2.0 认证源的时候,用户在本系统内的权限、详细用户信息等,仍需要在本地系统内维护;目前在国内支持度比较好的第三方认证源有:QQ、微信、微博、Github 等。下一节中,我们继续在 OAuth2.0 协议的基础上,构造出属于自己的认证中心。

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号