IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> RPC框架Dubbo --- 分布式服务【注册中心,接口工程】 -> 正文阅读

[网络协议]RPC框架Dubbo --- 分布式服务【注册中心,接口工程】

Dubbo框架


Dubbo框架: 基础


昨天简单介绍了REST的内容;纵观博主的博客,你可能会觉得基础,并且快 ,过几天一个框架,一个技术,最快的就是Mybatis了,两天就介绍完了,真的这么简单吗? 不是的 — 博主目前没有扩展深度,博主只是在扩展广度,也就是先要开拓视野; 你没了解Vue,你可能就不懂为啥要使用RESTful风格,费力不讨好,

Dubbo和Spring Cloud都是分布式的相关框架,何为分布式?这个后面会多次提到。

【这段时间,博主的重心在***上,该阶段还是会快速介绍很多需要使用的框架、中间件 — 可能有的就和之前的JQuery很快带过】

分布式 RPC remote procedure call 远程过程调用

分布式系统是若干独立的系统的集合,但是用户使用的体验就是一个系统; 随着业务的规模的逐步扩大,单台计算机不能承受住【such as 双十一的流量】 – 那就多个一起抗

应用的架构

  • 单一架构: 当网站流量很小的时候,将所有的应用业务放在一台服务器上,打包运行即可;开发和部署简单; 但是扩展不容易【 怎么处理日益增长的流量?】维护不容易,性能提升困难
  • 垂直应用架构: 将大应用拆分为小应用【按照业务拆分】,根据各个业务的访问频率决定各自业务部署的服务器的数量, 部署容易; 但是可能页面改变,就需要整个项目重新部署,业务和界面没有分隔开,服务器的交互效率问题,还有业务之间的关联关系
  • 分布式架构 基于RPC远程过程调用: 将业务拆分,用某种方式实现各个业务模块的远程调用和复用,这是一个好的RPC框架就决定了分布式架构的性能,怎么调用? 服务器挂了? 需要一个框架来管理(对于大流量,大公司各自使用不同的RPC框架来处理,而没有顶住就会宕机)

Dubbo

Dubbo时一个高性能的RPC框架【alibaba开发】,解决分布式的调用的问题

Apache Dubbo是一款高性能的、轻量级的java RPC框架,三大核心功能: 面向接口的远程方法调用,只能的容器和负载均衡、服务器的自动注册和发现; 是一个分布式服务的框架,提供高性能和透明化的RPC远程调用方案、服务治理方案

Dubbo特性: 面向接口代理的高性能RPC调用,服务是接口

Dubbo的注册中心可以管理调度,这里举一个例子【假设有100台服务器,50台处理用户业务,50台处理订单业务,但是上线后发现分配不合理,需要修改比例,就可以借助Dubbo实现】

高性能

高性能是因为Dubbo是一个RPC框架,就是远程过程调用,这里就涉及到了计算机网络的传输

]

远程方法调用,决定性能的关键因素就是序列化和网络通信:

序列化: java网络中就提到过: 本地的对象要在网络上传输,就要实现Serilizable接口,必须序列化,Dubbo就是采用的效率最高的二进制流进行序列化

网络通信: Http通信需要进行7步走【三次握手,四次挥手】---- 安全; Dubbo使用的是Socket即时通信机制一步到位,可以建立长连接,不用反复连接,直接进行传输

Dubbo Architecture

Container就是spring的容器,所以将provider注册到容器中,provider将服务注册到注册中心中,消费者就可以订阅相关的服务,订阅成功后,注册中心通知消费者订阅成功,同时消费者创建本地代理类来使用provider提供的服务

查看源图像

  • Consumer: 调用远程服务的服务消费方:, Consumer在启动的时候,向注册中心订阅自己所需要的服务,服务消费者,从提供者的地址列表中,基于软负载均衡算法,选择一台提供者进行调用,如果调用失败,就换一个
  • Monitor: 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心【哨兵】

dubbo支持协议

dubbo支持多种协议,比如dubbo、http、webservice、redis等,推荐使用dubbo协议,默认端口号20880

如果使用dubbo,使用的SSM架构,那么在Spring的配置文件中加入

<dubbo:protocol name="dubbo" port=“20880”/>

不依赖注册中心【直连方式】

在实际的操作中,是可以没有注册中心的,提供者直接提供服务,然后消费者事先知道有哪些服务,直接进行调用即可

首先这里就简单使用Spring创建项目,不创建SpringBoot项目,普通的maven项目即可

要想在项目中使用Dubbo,那么原始的Spring就需要在pom中手动添加依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.12</version>
</dependency>

当然项目中的容器就是spring的容器,所以需要spring的相关依赖,context和webmvc

    <!-- spring依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
        
这里目前来说有点魔幻,mvc中有context,但是不配置context;就会报错jar包冲突.....后面再康康

同时dubbo底层是依赖netty实现的,所以要加入netty的依赖: java.lang.ClassNotFoundException: io.netty.channel.EventLoopGroup

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>4.1.32.Final</version>
</dependency>

创建服务提供者的相关对象和方法

package chuan.model;

public class Student {
    private int stuNo;
    private  String stuName;
    private  String stuClass;

    
//上面就是一个普通的实体类,服务者提供的接口方法
package chuan.service;

import chuan.model.Student;

public interface StudentService {
    //根据姓名查询学生
    Student queryStudentByName(String userName);
}

provider提供的服务就是该业务方法,因为Dubbo的特性就是面向接口,接口为最小的粒度【其实就是代理模式,所以最终执行的还是实现类,创建一个实现类】

package chuan.service.impl;

import chuan.model.Student;
import chuan.service.StudentService;

public class StudentServiceImpl implements StudentService {
    @Override
    public Student queryStudentByName(String userName) {
        //这里本来需要访问Dao进行处理,这里简化一点,毕竟不是庞大的技术
        Student student = new Student();
        student.setStuNo(1);
        student.setStuName("Cfeng");
        student.setStuClass("HC2001");
        return student;
    }
}

配置provider的核心配置文件【声明、协议、暴露服务 application protocol service 】

provider要将服务给暴露出去,就必须进行配置【最后会分享springBoot的简化版】,配置的内容包括服务提供者的名称applicaiton, 服务的协议protocol,暴露的服务接口service — 如果不使用注册中心,那么就通过registry属性为N/A; 服务包括接口,和其具体的实现类对象

<?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.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 简单使用组件扫描器扫描标签-->
    <context:component-scan base-package="chuan.service"/>

    <!-- 服务者声明名称,一个xml文件对应的是一个服务者,必须保证服务名称的唯一性,dubbo内部使用的唯一标识-->
    <dubbo:application name="stuServiceProvider"/>

    <!-- 调用服务协议的名称和端口号,推荐使用dubbo协议-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 暴露的服务的接口,全限定类名,ref引用的是接口的实现类;service对象 ; 并且这里没有使用注册中心,所以需要使用registry指定N/A-->
    <dubbo:service interface="chuan.service.StudentService" ref="studentService" registry="N/A"/>
</beans>
  • 接下来就是将这个spring配置文件【容器】在项目启动的时候加载;SSM中就需要在web.xml中手动进行配置,将spring容器挂载到全局的监听器中
<!-- 注册监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 指定监听器扫描的spring配置文件的位置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-stuService-provider.xml</param-value>
    </context-param>

这样项目启动的时候就会扫描spring容器并且加载这个provider【provider依赖的Spring容器】

创建消费者consumer【不同的服务器上,port不同】

创建的步骤和提供者类似,首先就是建立一个项目【这是分布式框架,不是在同一个服务器或者项目中】

  • 创建pom文件,添加dubbo和spring的依赖

这里需要使用另外一个项目的服务,那么就就必须加入依赖…,所以先对项目进行jar打包到本地仓库,然后导入依赖

//首先将上面的服务提供module打包jar包 【服务提供者没有controller是因为这是分布式架构,服务者就只是分担服务压力而已】
    <!-- 服务提供者的依赖-->
    <dependency>
      <groupId>Chuan</groupId>
      <artifactId>dubbo-001</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

Caused by: java.lang.NoSuchMethodError: ‘org.springframework.context.ApplicationContext org.springframework.web.servlet.handler.AbstractHandlerMapping.obtainApplicationContext()’

这个错误是经典报错,所以记录一下,这是因为依赖项冲突,也就是重复的依赖, 这里很明显,因为导入的前一个项目已经将很多的依赖添加过了,所以直接删除即可;只保留该依赖项

配置dubbo的核心配置文件【声明,引用服务】

这里的配置和上面还是稍微一些不同,上面需要暴露服务,而这里只是需要引用服务

但是还是要声明应用的名称来让dubbo进行标识【至于为什么是application可以看到这是每一个module项目就一个配置,所以当然就是application了,dubbo管理的就是一个个应用,只是这些应用发挥的功能不同,分布式提供服务】

还要使用reference来指明要使用的provider的服务,id指定要使用的实现类对象,这个不是用来标识实现类对象的,是根据version来标识的,id不能重复,只是对于这个引用的服务进行id命名而已、interface指定服务者提供的接口interface,url就是默认的协议dubbo://localhost:20880, 同时还要表明为直连方式registry为N/A

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 声明应用的名称,dubbo识别的唯一标识 -->
    <dubbo:application name="serviceConsumer"/>
    <!-- 声明要使用的服务,要指定provider提供的服务的接口和其实现类对象,同时指定路径url,和直连与否 -->
    <dubbo:reference id="studentService" interface="chuan.service.StudentService" registry="N/A" url="dubbo://localhost:20880"/>
</beans>

这里的springMVC的配置文件懒得新开了,就写一起了,反正也是父子关系【SpringBoot也没有分开了】,就一个组件扫描器和注解驱动

id就是标识这个引用的,就类似之前的bean,这里因为只有一个实现类对象,所以引用的时候就会直接调用Dubbo中的service实现类对象,如果有多个就通过vetrsion进行标识

所以就简单两行即可

<context:component-scan base-package="Clei.controller"/>

 <mvc:annotation-driven/>
  • 编写controller来使用这个服务;【需要在web.xml中配置中央调度器】
package clei.controller;

import chuan.model.Student;
import chuan.service.StudentService;  //添加了依赖,可以直接使用
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class stuController {
    //Dubbo对象序列化,provider提供的对象是可以直接使用
    @Resource
    private StudentService studentService;

    @RequestMapping("/user")
    public Student queryStudent() {
        return studentService.queryStudentByName("Clei");
    }
}

配置中央调度器,直接通过init-param来指定两个文件

  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <!-- 这里就可以直接通过中央调度器来加载者两个文件 -->
      <param-value>classpath:dubbo-consumer.xml,classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

java.lang.IllegalStateException: Serialized class chuan.model.Student must implement java.io.Serializable

这里很明显,因为dubbo对象的传输依赖的是序列化,实体类必须实现Seriali接口

public class Student  implements Serializable {

这里可能会有疑问?

在Consumer中直接使用接口实现类不就行了?

    public Student queryStudent() {
        StudentService studentService = new StudentServiceImpl();
        return studentService.queryStudentByName("Clei");
    }

但是这样做和Dubbo就没有关系了,这就是一个简单的包依赖和调用

接口工程

所以Dubbo就要求工程中有一个接口工程: 就是一个maven java工程;要求接口工程中存放的内容:

  • 对外暴露的服务接口service的interface
  • 实体bean对象

这样子中间有了接口工程来中转,就不需要再导入依赖,并且不会产生为何不直接使用对象的方法的困惑了,因为届时就不能这样操作了

Dubbo服务化

分包【中间接口module】

dubbo中建议将所有的服务接口、服务模型放在公共包中【业务接口工程】

Dubbo标签

Dubbo中常用的标签,分为3个类别: 公用标签、服务提供者标签和服务消费者标签

公用标签

application: 指定应用module的名称【dubbo的唯一标识】 ----- 配置应用信息

registry: 指定注册中心 ----- 配置注册中心

<dubbo:applicaiton name="服务名称"/>

<dubbo:registry address="ip:port" protocol="协议"/>

粒度

服务接口的粒度要尽可能大,每个服务方法中应该代表一个功能,而不是一个功能的步骤

服务接口建议是按照业务场景为单位划分,并且要对相近的业务进行抽象,防止接口数量爆满

不适用过于抽象的通用接口,比如Map query(Map) 这样的接口没有具体的意义,不方便维护

稳定性

Dubbo具有高稳定性,当服务提供者宕机了,那么消费者就是不能正常进行访问,只有提供者状态正常,消费者才能够正常使用服务

配置属性

在服务提供者配置访问参数,因为服务提供者更了解服务的各种参数

consumer的check属性

dubbo缺省,启动的时候会自动检查服务是否可用,不可用会抛出异常,阻止spring容器的初始化,也就是应用服务的属性;一般在开发的时候关闭自动检测

关闭某个服务的自动检查

<dubbo:refrence interface="xxxx" id=""  url =""  check= "false"/>

关闭注册中心启动的自动检查

<dubbo:registry adress="" check="false"/>

重试次数retries

消费者访问提供者,如果访问失败,就会尝试访问其他的服务器,但是重试的延迟更大,访问时间变长,用户体验不好,可以通过retries设置

<dubbo:service interface="" ref vresion  retries="2"/>   这里可以不用设置

超时时间timout

重试次数有点不方便,可以直接设置超时时间,最长加载多少毫秒就失败

<dubbo:service interface="" ref vresion  timout="2000"/> 

版本【同一个接口的不同实现类】 Service的version属性

每个接口都应定义版本号,区分统一接口的不同实现;

<dubbo:service interface= "XXX" version="1.0"/>  不同的ref

项目改造–直边方式【使用接口工程做中转】

这里新建一个普通的maven项目,也就是一个quickstart的项目,这种方式主要的就是将公共的内容剥离到接口工程中;也就是实体bean和公共的业务接口

首先就先表明和上面的不同的地方:

  • 创建了新的module—接口工程 【将之前的provider中的实体bean和业务接口放入】
  • provider只需要对接口工程的接口进行实现【配置文件的service的interface指定】
  • 接口工程的pom.xml只需要dubbo的依赖和netty-all依赖
  • provider和consumer都依赖接口工程,consumer中的配置文件和controller的接口引入修改位置

provider

controller的服务的实现类

package chuan.service.impl;

import Csheng.model.Student;
import Csheng.service.StudentService;
import org.springframework.stereotype.Service;

@Service("studentService")
public class StudentServiceImpl implements StudentService {
    @Override
    public Student queryStudentByName(String userName) {
        //这里本来需要访问Dao进行处理,这里简化一点,毕竟不是庞大的技术
        Student student = new Student();
        student.setStuNo(1);
        student.setStuName("Cfeng++");
        student.setStuClass("HC2001");
        return student;
    }
}

配置文件【声明,协议、暴露服务】

   <!-- 简单使用组件扫描器扫描标签-->
    <context:component-scan base-package="chuan.service"/>

    <!-- 服务者声明名称,一个xml文件对应的是一个服务者,必须保证服务名称的唯一性,dubbo内部使用的唯一标识-->
    <dubbo:application name="stuServiceProvider"/>

    <!-- 调用服务协议的名称和端口号,推荐使用dubbo协议-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 暴露的服务的接口,全限定类名,ref引用的是接口的实现类;service对象 ; 并且这里没有使用注册中心,所以需要使用registry指定N/A-->
    <dubbo:service interface="Csheng.service.StudentService" ref="studentService" registry="N/A"/>

然后在web.xml中使用监听器将spring容器创建即可;容器中有service的实现类对象;Dubbo协议传输该对象

interface proj

实体bean【一定要序列化】

package Csheng.model;

import java.io.Serializable;

public class Student  implements Serializable {
    private int stuNo;
    private  String stuName;
    private  String stuClass;

服务接口【适当的抽象化】

package Csheng.service;

import Csheng.model.Student;

public interface StudentService {
    //根据姓名查询学生
    Student queryStudentByName(String userName);
}

consumer

pom中要添加接口工程的依赖,因为要订阅服务【接口】;可能使用到其中的实体bean

controller示例:

package clei.controller;

import Csheng.model.Student;
import Csheng.service.StudentService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

@Controller
public class stuController {
    //Dubbo对象序列化,provider提供的对象是可以直接使用
    @Resource
    private StudentService studentService;

    @RequestMapping("/hello")
    @ResponseBody
    public Student queryStudent() {
        System.out.println("nihao");
        return studentService.queryStudentByName("Clei");
    }
}

配置文件【 web.xml配置中央处理器就不演示了】

<!-- 声明应用的名称,dubbo识别的唯一标识 -->
    <dubbo:application name="serviceConsumer"/>
    <!-- 声明要使用的服务,要指定provider提供的服务的接口和其实现类对象,同时指定路径url,和直连与否 -->
    <dubbo:reference id="studentService" interface="Csheng.service.StudentService" registry="N/A" url="dubbo://localhost:20880"/>

这里使用的service对象就是之前的provider的spring容器中的,遵循dubbo协议,直接使用这个对象

这样运行provider和consumer就可以正常进行显示;需要注意的是: 使用接口工程就解决了之前的困惑,因为consumer不依赖provider,那么就不能够直接new provider中的接口实现类; 必须通过Dubbo的方式来使用这个对象

监控中心

Dubbo的使用,只需要有消费者、提供者和注册中心三者即可,当时不能看到有哪些消费者和提供者,为了更好发现问题,引入dubbo-admin,可以对…进行管理

dubbo-admin — 配合注册中心图形化管理服务

图形化的服务管理页面,安装需要指定注册中心地址,就可以从注册中心获取到所有的提供者和消费者进行配置管理

注册中心Zookeeper

上面的接口工程就已经稍微优化了直连的方式,但是对于服务提供方,需要发布服务,由于应用系统的复杂性,服务的数量和类型都是不断膨胀的,接口工程不方便管理庞大的服务;服务消费方只是需要使用到需要使用到的服务;对于提供方和消费方来说,可能既要提供服务,也要消费服务

所以需要将服务统一管理起来,可以有效优化内部应用对服务发布和使用的管理,服务注册中心可以通过特定的i下而已完成服务对外的统一,Dubbo提供的注册中心有: Multicast、Redis、Simple、zookeeper;推荐使用Zookeeper是一个树形的目录服务,支持变更推送,适合Dubbo服务的注册中心【就是一个记录服务的module】

查看源图像

可以看到最上面的就是Dubbo根结点,下面就是一个个服务【接口】,接口下面就是该服务的消费者和提供者,在下面的叶子结点就是provider和consumer的url

下载配置Zookeeper

进入官网下载即可: Apache ZooKeeper 【ZooKeeper 动物园管理者】 — 动物就是服务【接口】

需要注意的是,从3.5版本之后,普通的tar.gz只是源码,不能直接运行,所以需要下载带有bin的;这里给一个直接下载的地址: Index of /dist/zookeeper/zookeeper-3.8.0 (apache.org)

下载之后解压到相关的目录,接下来就是修改一个配置文件,将zoo-cfg复制,创建修改

dataDir=D:/zookeeper/apache-zookeeper-3.8.0/data   #创建了一个data目录

clientPort=2181
admin.serverPort = 8888  #设置运行的程序的端口号,默认是8080,修改为8888

点击bin下面的server.cmd就可以直接运行

2022-04-07 22:06:11,895 [myid:] - INFO  [main:o.a.z.s.NIOServerCnxnFactory@660] - binding to port 0.0.0.0/0.0.0.0:2181

使用zookeeper示例

之前我们已经使用了一个接口工程来优化直连的方式,但是这样子还是不方便直观的管理规模庞大的provider和consumer;这里就可以引入zookeeper;还是先来说相比之前的接口直边方式的不同之处

  • 引入zookeeper的依赖curator,这里就将依赖放在接口工程中
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.2.0</version>
</dependency>
  • provider和consumer的配置文件都将对应的registry属性删掉,然后添加一个registry结点,指定address
<dubbo:registry address="zookeeper://localhost:2181"  //这里的端口就是之前占用的端口

在linux中进行部署的区别就是不同的ip地址即可

所以没有太大的变化;在开启的时候,将不同的module运行起来并且将zookeeper运行起来

版本号version — 同一接口不同实现

在实际开发中可能出现的问题就是,版本的迭代,因为面向接口编程,然后对于同一个服务接口,可能有了更好的实现类,但是按照之前的接口工程,在暴露服务的时候interface指向接口,ref指向实现类; 只是暴露了一个服务;现在版本迭代,想要多个版本的服务都支持,那么就要使用暴露多个服务

这里和上面相比的不同点

  • provider配置文件中要暴露多个服务【不同的实现类】,增加一个verison属性,ref引用不同的对象注入到对应的version中
  • consumer的配置文件中,可以同时接收同一接口的不同的实现服务;通过id标识当前应用的服务,version指定版本,这样就可以通过dubbo将对应的Service对象传输到Consumer中使用
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:53:50  更:2022-04-09 18:54:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/31 3:34:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码