精华内容
下载资源
问答
  • 这是一个Neo4j Haskell驱动程序,用于使用Bolt协议连接到Neo4j图形数据库。 该存储库是实验性的,驱动程序不完整,仍在开发中,不适用于任何正式发行的Neo4j版本。 该驱动程序旨在与Neoj4的将来版本(尚未发布)...
  • 使用官方Cassandra CQL3二进制协议进行连接的会话存储。 安装 npm install connect-cassandra-cql 用法 快递4 var express = require ( 'express' ) , cookieParser = require ( 'cookie-parser' ) , session ...
  • MQTT协议_连接

    万次阅读 2018-02-06 13:00:41
     在发送MQTT connect报文之前,必须确保底层提供了有序、可靠、双向连接的网络连接。比如可以建立TCP/TLS连接。 2.4.1.1 报文格式 Connect控制报文包括固定报文和可变报文,以及有效载荷三个部分。 有效载荷包含...

    CONNECT

           在发送MQTT connect报文之前,必须确保底层提供了有序、可靠、双向连接的网络连接。比如可以建立TCP/TLS连接。

    2.4.1.1 报文格式

    Connect控制报文包括固定报文和可变报文,以及有效载荷三个部分。

    有效载荷包含一个或多个编码的字段。包括客户端的唯一标识符,Will主题,Will消息,用户名和密码。除了客户端标识之外,其它的字段都是可选的,基于可变报头中标志位来决定可变报头中是否需要包含这些字段。

    Ø 固定报头

    长度:2bytes

    包括报文类型(1),固定保留位(0000)和剩余长度。

    剩余长度等于可变报头的长度(10字节)加上有效载荷的长度。

    Ø 可变报头

    长度:10bytes。

    CONNECT报文的可变报头按下列次序包含四个字段:

    • 协议名(Protocol Name)
    • 协议级别(Protocol Level)
    • 连接标志(Connect Flags)
    • 保持连接(Keep Alive)。

    我们接下来按照这个顺序依次来介绍这些字段。

    协议名(Protocol Name

    长度:6bytes

    数据包检测工具,例如防火墙,可以使用协议名来识别MQTT流量。

    如果协议名不正确服务端可以断开客户端的连接,也可以按照某些其它规范继续处理CONNECT报文。对于后一种情况,按照本规范,服务端不能继续处理CONNECT报文(比如MQTT-3.1.1);

    协议级别(Protocol Level

    长度:1byte

    客户端用8位的无符号值表示协议的修订版本。对于3.1.1版协议,协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。

    连接标志(Connect Flags

    连接标志字节包含一些用于指定MQTT连接行为的参数。它还指出有效载荷中的字段是否存在。

    服务端必须验证CONNECT控制报文中连接标志的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。

    ü  Clean Session:

    控制初次连接或是重连时候,服务器对于会话的处理方式。

    • 0:

    如果没有与这个客户端标识符关联的会话,服务端必须创建一个新的会话。

    如果是重连,服务端必须基于当前会话(使用客户端标识符识别)的状态恢复与客户端的通信。当连接断开后,客户端和服务端必须保存会话信息。

    如果在断开连接之前,客户端订阅了QoS1和QoS2级别的消息,那么服务端必须将之后的QoS 1和QoS 2级别的消息保存为会话状态的一部分。服务端也可以保存满足相同条件的QoS 0级别的消息。

    •  1:

    客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。会话仅持续和网络连接同样长的时间。与这个会话关联的状态数据不能被任何之后的会话重用。

    当清理会话标志被设置为1时,客户端和服务端的状态删除不需要是原子操作。

    ü  Will Flag:

    用于控制遗嘱消息(will Message)的操作行为。

    一般来说,客户端连接时总是将清理会话标志设置为0或1,并且不交替使用两种值。这个选择取决于具体的应用。清理会话标志设置为1的客户端不会收到旧的应用消息,而且在每次连接成功后都需要重新订阅任何相关的主题。清理会话标志设置为0的客户端会收到所有在它连接断开期间发布的QoS 1和QoS 2级别的消息。因此,要确保不丢失连接断开期间的消息,需要使用QoS 1或 QoS 2级别,同时将清理会话标志设置为0。

    • 1:

      表示如果连接请求被接受了,遗嘱(Will Message)消息必须被存储在服务端并且与这个网络连接关联。之后网络连接关闭(没有收到DISCONNET报文)时,服务端必须发布这个遗嘱消息。如果服务器收到DISCONNET报文,遗嘱消息将会被删除。

      连接标志中的Will QoS和Will Retain字段会被服务端用到,同时有效载荷中必须包含Will Topic和Will Message字段。

    • 0:

      网络连接断开时,不能发送遗嘱消息

      连接标志中的Will QoS和Will Retain字段必须设置为0,并且有效载荷中不能包含Will Topic和Will Message字段

    ü  Will Qos:

    这两位用于指定发布遗嘱消息时使用的服务质量等级,和will flag配合使用。

    •   如果遗嘱标志被设置为0,遗嘱QoS也必须设置为0(0x00)。
    •   如果遗嘱标志被设置为1,遗嘱QoS的值可以等于0(0x00),1(0x01),2(0x02)。它的值不能等于3

    ü  Will Retain:

    遗嘱保留,如果遗嘱消息被发布时需要保留,需要指定这一位的值,和will flag位配合使用。

    •   如果遗嘱标志被设置为0,遗嘱保留(Will Retain)标志也必须设置为0。
    •   如果遗嘱标志被设置为1:

       --- 如果遗嘱保留被设置为0,服务端必须将遗嘱消息当作非保留消息发布。

       --- 如果遗嘱保留被设置为1,服务端必须将遗嘱消息当作保留消息发布。

    ü  PassWordFlag:

    • n  0:有效载荷中不能包含密码字段;
    • n  1:有效载荷中必须包含密码字段

    ü  UserName Flag:

    • n  0:有效载荷中不能包含用户名字段;
    • n  1:有效载荷中必须包含用户名字段

    保持连接

    长度:2bytes

    保持连接(KeepAlive)是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。

    不管保持连接的值是多少,客户端任何时候都可以发送PINGREQ报文,并且使用PINGRESP报文判断网络和服务端的活动状态。

    如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开。

    客户端发送了PINGREQ报文之后,如果在合理的时间内仍没有收到PINGRESP报文,它应该关闭到服务端的网络连接。

    保持连接的值为零表示关闭保持连接功能。这意味着,服务端不需要因为客户端不活跃而断开连接。注意:不管保持连接的值是多少,任何时候,只要服务端认为客户端是不活跃或无响应的,可以断开客户端的连接。

    保持连接的实际值是由应用指定的,一般是几分钟。允许的最大值是18小时12分15秒,即65535,uint16

    典型的可变报文格式如下:

    Ø 有效载荷

    CONNECT报文的有效载荷(payload)包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码。

    客户端标识符

    服务端使用客户端标识符 (ClientId) 识别客户端。连接服务端的每个客户端都有唯一的客户端标识符(ClientId)。客户端和服务端都必须使用ClientId识别两者之间的MQTT会话相关的状态。

    客户端标识符 (ClientId) 必须存在而且必须是CONNECT报文有效载荷的第一个字段。

    客户端标识符必须是1.5.3节定义的UTF-8编码字符串。

    服务端必须允许1到23个字节长的UTF-8编码的客户端标识符,客户端标识符只能包含这些字符:“0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”(大写字母,小写字母和数字);

    服务端可以允许编码后超过23个字节的客户端标识符(ClientId)。服务端可以允许包含不是上面列表字符的客户端标识符 (ClientId)。

    服务端可以允许客户端提供一个零字节的客户端标识符 (ClientId) ,如果这样做了,服务端必须将这看作特殊情况并分配唯一的客户端标识符给那个客户端。然后它必须假设客户端提供了那个唯一的客户端标识符,正常处理这个CONNECT报文。

    如果客户端提供了一个零字节的客户端标识符,它必须同时将清理会话标志设置为1。如果客户端提供的ClientId为零字节且清理会话标志为0,服务端必须发送返回码为0x02(表示标识符不合格)的CONNACK报文响应客户端的CONNECT报文,然后关闭网络连接。

    如果服务端拒绝了这个ClientId,它必须发送返回码为0x02(表示标识符不合格)的CONNACK报文响应客户端的CONNECT报文,然后关闭网络连接。

    客户端实现可以提供一个方便的方法用于生成随机的ClientId。当清理会话标志被设置为0时应该主动放弃使用这种方法。

    遗嘱主题

    如果遗嘱标志被设置为1,有效载荷的下一个字段是遗嘱主题(Will Topic)。遗嘱主题必须是 1.5.3节定义的UTF-8编码字符串。

    遗嘱消息

    如果遗嘱标志被设置为1,有效载荷的下一个字段是遗嘱消息。遗嘱消息定义了将被发布到遗嘱主题的应用消息,见3.1.2.5节的描述。

    这个字段由一个两字节的长度(表示为零字节或多个字节序列)和遗嘱消息的有效载荷组成。长度给出了跟在后面的数据的字节数,不包含长度字段本身占用的两个字节。

    遗嘱消息被发布到遗嘱主题时,它的有效载荷只包含这个字段的数据部分,不包含开头的两个长度字节。

    用户名

    如果用户名(User Name)标志被设置为1,有效载荷的下一个字段就是它。用户名必须是 1.5.3节定义的UTF-8编码字符串 [MQTT-3.1.3-11]。服务端可以将它用于身份验证和授权。

    密码

    如果密码(Password)标志被设置为1,有效载荷的下一个字段就是它。密码字段包含一个两字节的长度字段,长度表示二进制数据的字节数(不包含长度字段本身占用的两个字节),后面跟着0到65535字节的二进制数据。

    2.4.1.2 服务器端响应

    服务器可以在同一个TCP端口或其他网络端点上支持多种协议(包括本协议的早期版本)。

    如果服务器确定协议是MQTT 3.1.1,那么它按照下面的方法验证连接请求。

    • Ø  网络连接建立后,如果服务端在合理的时间内没有收到CONNECT报文,服务端应该关闭这个连接。
    • Ø  服务端必须按照3.1节的要求验证CONNECT报文,如果报文不符合规范,服务端不发送CONNACK报文直接关闭网络连接 [MQTT-3.1.4-1]。
    • Ø  服务端可以检查CONNECT报文的内容是不是满足任何进一步的限制,可以执行身份验证和授权检查。如果任何一项检查没通过,按照3.2节的描述,它应该发送一个适当的、返回码非零的CONNACK响应,并且必须关闭这个网络连接。

    如果验证成功,服务端会执行下列步骤。

    • Ø  如果ClientId表明客户端已经连接到这个服务端,那么服务端必须断开原有的客户端连接。
    • Ø  服务端必须按照 3.1.2.4节的描述执行清理会话的过程(clean session = 1)。
    • Ø  服务端必须发送返回码为零的CONNACK报文作为CONNECT报文的确认响应。
    • Ø  开始消息分发和保持连接状态监视。

    允许客户端在发送CONNECT报文之后立即发送其它的控制报文;客户端不需要等待服务端的CONNACK报文。如果服务端拒绝了CONNECT,它不能处理客户端在CONNECT报文之后发送的任何数据。

    客户端通常会等待一个CONNACK报文。然而客户端有权在收到CONNACK之前发送控制报文,由于不需要维持连接状态,这可以简化客户端的实现。

    2.4.1.3服务器异常处理

    Ø  重复发送connect报文

    在一个网络连接上,客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接。

    Ø  协议名不正确

    如果协议名不正确服务端可以断开客户端的连接,也可以按照某些其它规范继续处理CONNECT报文。对于后一种情况,按照本规范,服务端不能继续处理CONNECT报文(比如MQTT3.1.1);

    Ø  不支持的协议级别

    如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。

    Ø  连接标志字段中的保留位验证失败

    服务端必须验证CONNECT控制报文中连接标志的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。

    Ø  客户端发送PINGREQ报文,服务器端超时无反应

    如果在合理的时间内仍没有收到PINGRESP报文,它应该关闭到服务端的网络连接。

    Ø  服务器端长时间未收到客户端的报文

    如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文或是PINGRESP报文,它必须断开客户端的网络连接,认为网络连接已断开。

    Ø  服务器端收到ClientID为0但是ClearSession为0的报文

    如果客户端提供的ClientId为零字节且清理会话标志为0,服务端必须发送返回码为0x02(表示标识符不合格)的CONNACK报文响应客户端的CONNECT报文,然后关闭网络连接。

    Ø  服务器端收到非法的ClientID报文请求

    如果服务端拒绝了这个ClientId,它必须发送返回码为0x02(表示标识符不合格)的CONNACK报文响应客户端的CONNECT报文,然后关闭网络连接。

    2.4.1.3 实际案例

    本案例基于Ali 云OS的MQTT通信协议。从他们的开发文档来看,是有一些修改,不过大致过程是一样的。

    1)连接配置

    所有mqtt连接的配置来着如下的两个结构体:

    /* The structure of MQTT initial parameter */

    typedef struct {

        uint16_t                    port;                   /* Specify MQTT broker port */

        const char                 *host;                   /* Specify MQTT broker host */

        const char                 *client_id;              /* Specify MQTT connection client id*/

        const char                 *username;               /* Specify MQTT user name */

        const char                 *password;               /* Specify MQTT password */

     

        /* Specify MQTT transport channel and key.

       * If the value is NULL, it means that use TCP channel,

         * If the value is NOT NULL, it means that use SSL/TLS channel and

         *   @pub_key point to the CA certification */

        const char                 *pub_key;

     

        uint8_t                     clean_session;            /* Specify MQTT clean session or not*/

        uint32_t                    request_timeout_ms;       /* Specify timeout of a MQTT request in millisecond */

        uint32_t                    keepalive_interval_ms;    /* Specify MQTT keep-alive interval in millisecond */

     

        char                       *pwrite_buf;               /* Specify write-buffer */

        uint32_t                    write_buf_size;           /* Specify size of write-buffer in byte */

        char                       *pread_buf;                /* Specify read-buffer */

        uint32_t                    read_buf_size;            /* Specify size of read-buffer in byte */

     

        iotx_mqtt_event_handle_t    handle_event;             /* Specify MQTT event handle */

     

    } iotx_mqtt_param_t, *iotx_mqtt_param_pt;

    typedef struct

    {

            /** The eyecatcher for this structure.  must be MQTC. */

            char struct_id[4];

            /** The version number of this structure.  Must be 0 */

            int struct_version;

            /** Version of MQTT to be used.  3 = 3.1 4 = 3.1.1

              */

            unsigned char MQTTVersion;

            MQTTString clientID;

            unsigned short keepAliveInterval; //鍗曚綅s

            unsigned char cleansession;

            unsigned char willFlag;

            MQTTPacket_willOptions will;

            MQTTString username;

            MQTTString password;

    } MQTTPacket_connectData;

    #define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, KEEP_ALIVE_INTERVAL_DEFAULT_MIN, 1, 0, \

    MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }

    其中iotx_mqtt_param_t结构体通过如下的代码完成初始化数据的填充。

        /* Device AUTH */

        if (0 != IOT_SetupConnInfo(PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, (void **)&pconn_info)) {

            EXAMPLE_TRACE("AUTH request failed!");

            rc = -1;

            goto do_exit;

        }

     

        /* Initialize MQTT parameter */

        memset(&mqtt_params, 0x0, sizeof(mqtt_params));

     

        mqtt_params.port = pconn_info->port;

        mqtt_params.host = pconn_info->host_name;

        mqtt_params.client_id = pconn_info->client_id;

        mqtt_params.username = pconn_info->username;

        mqtt_params.password = pconn_info->password;

        mqtt_params.pub_key = pconn_info->pub_key;

     

        mqtt_params.request_timeout_ms = 2000;

        mqtt_params.clean_session = 0;

        mqtt_params.keepalive_interval_ms = 60000;

        mqtt_params.pread_buf = msg_readbuf;

        mqtt_params.read_buf_size = MSG_LEN_MAX;

        mqtt_params.pwrite_buf = msg_buf;

        mqtt_params.write_buf_size = MSG_LEN_MAX;

     

        mqtt_params.handle_event.h_fp = event_handle;

        mqtt_params.handle_event.pcontext = NULL;

           然后调用iotx_mc_set_connect_params()函数,

     

        MQTTPacket_connectData connectdata = MQTTPacket_connectData_initializer;

        connectdata.MQTTVersion = IOTX_MC_MQTT_VERSION;

        connectdata.keepAliveInterval = pInitParams->keepalive_interval_ms / 1000;

     

        connectdata.clientID.cstring = (char *)pInitParams->client_id;

        connectdata.username.cstring = (char *)pInitParams->username;

        connectdata.password.cstring = (char *)pInitParams->password;

    2)包空间申请

    在Aliyun的MQTT协议的实现中,是通过预先malloc一个1K大小的Buffer用来作为send_buf的,并将指针通过一系列的赋值,传递到第3步。

    顺便多提下,Aliyun在实现的过程也同时预先malloc一个1K大小的Buffer用来作为read_buf。

    3)组包过程

    在网络编程或是寄存器编程中,有个常用的办法就是利用联合体的方式。比如,在组成固定包头中,编程过程中定义了联合体MQTTHeader。

           使用的办法参考下面的代码。

           而连接标志字段的填充也是利用了联合体的特性。注意是小端格式。

     

    /**

      * Serializes the connect options into the buffer.

      * @param buf the buffer into which the packet will be serialized

      * @param len the length in bytes of the supplied buffer

      * @param options the options to be used to build the connect packet

      * @return serialized length, or error if 0

      */

    int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options)

    {

           unsigned char *ptr = buf;

           MQTTHeader header = {0};

           MQTTConnectFlags flags = {0};

           int len = 0;

           int rc = -1;

     

           if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)

           {

                  rc = MQTTPACKET_BUFFER_TOO_SHORT;

                  goto exit;

           }

    // header是一个联合体。CONNECT定义的值为1

           header.byte = 0;

           header.bits.type = CONNECT;

           writeChar(&ptr, header.byte); /* write header */

    // 写入固定报头的第二个字节,即剩余长度。

           ptr += MQTTPacket_encode(ptr, len); /* write remaining length */

     

    // 写入可变报头中的协议名称和协议等级字段

           if (options->MQTTVersion == 4)

           {

                  writeCString(&ptr, "MQTT");

                  writeChar(&ptr, (char) 4);

           }

           else

           {

                  writeCString(&ptr, "MQIsdp");

                  writeChar(&ptr, (char) 3);

           }

     

    // flags是定义的联合体,按照默认的配置cleansession=1,willFlag= 0

           flags.all = 0;

           flags.bits.cleansession = options->cleansession;

           flags.bits.will = (options->willFlag) ? 1 : 0;

           if (flags.bits.will)

           {

                  flags.bits.willQoS = options->will.qos;

                  flags.bits.willRetain = options->will.retained;

           }

     

           if (options->username.cstring || options->username.lenstring.data)

                  flags.bits.username = 1;

           if (options->password.cstring || options->password.lenstring.data)

                  flags.bits.password = 1;

           writeChar(&ptr, flags.all);

     

    // 组合可变报头中的保持连接(Keep Alive)长度

           writeInt(&ptr, options->keepAliveInterval);

     

    // 组合有效载荷中的客户端标识符

           writeMQTTString(&ptr, options->clientID);

     

    // 组合有效载荷中的遗嘱主题,遗嘱消息(如果willFlag =1)

           if (options->willFlag)

           {

                  writeMQTTString(&ptr, options->will.topicName);

                  writeMQTTString(&ptr, options->will.message);

           }

     

    // 组合有效载荷中的用户名字,

           if (flags.bits.username)

                  writeMQTTString(&ptr, options->username);

     

    // 组合有效载荷中的密码,

           if (flags.bits.password)

                  writeMQTTString(&ptr, options->password);

     

           rc = ptr - buf;

     

    exit:

           return rc;

    }

           固定报头中,关于剩余长度的计算过程:

    4)发送

    直接调用底层的发送函数发送即可。是实际的实现过程中,需要在客户端新建一个定时器,用来监听是否按时收到CONNACK。如果没有及时收到CONNACK,客户端应该断开网络连接,这个超时时间需要根据应用类型和通信环境,我们在本例程中设置的时间是2000ms。

    当然,协议运行客户端在收到CONNACK之前发送其他的控制报文。


    展开全文
  • 最完整的存储系统接口/协议/连接方式总结,没有之一。打赏即可得PPT原稿。

         声明:只要在本页面底部赞赏 2元或以上 者,冬瓜哥便将本文中的配图PPT原稿推送给你,每天晚上在公众号上统一对已打赏的朋友推送原稿。来吧,兄弟们!!


        上周,冬瓜哥写过一篇各种存储接口协议总结,不过是篇比较初步的。本次,冬瓜哥打算图文并茂的完整总结一下常见的存储协议接口连接器。


      一.顶层协议描述了什么

        在存储系统中,上层协议可以泛指“指令”,也就是比如“读出从某某开始的多少长度的扇区”,读/写类指令包含三大关键信息:

    1.    操作码 ,OperationCode,或者称为OP code。比如Write,Read,Control(Inquery,Standby等等)。

    2.    起始地址 :从哪开始读。如果是文件的话,精确到字节。如果是硬盘的话,精确到LBA(扇区)。

    3.    长度 :从起始地址往后多长的一段字节或者扇区。

    二.下层协议及接口又是做什么用的

            那么,指令如果传递给对端的设备?你可以自己将上述指令的二进制码再编码一下,用手电筒的量灭传递给对方,传对方收到之后闪一下手电筒表示已经收到。此时,手电筒编码、收到后怎么表示收到,这也是一种协议,属于传输层协议。而手电筒就是物理层的接口,最终通过物理层,也就是光在真空中传播来将信息发送到对方。  

            同理,SCSI指令/协议和NVMe指令/协议,是存储系统面向机械盘和固态介质分别开发的两种上层协议。它们可以被over到传输层协议+网络层/链路层/物理层接口上传输到对方,比如scsi over fc,scsi over sas、[(scsiover tcp)over ip] over ethernet(iSCSI), scsi over RDMA over IB(SRP), scsi over tcp over ip over ib。以及NVMe over PCIE over 标准插槽、NVMe over PCIE overM.2接口、NVMe over PCIE over SFF8639接口等等。

            NVMe 最好是直接over到PCIE上,因为目前来讲,PCIE的物理层+链路层+网络层+传输层还是非常高效的,算是开放式IT设备外部IO总线里速率较高使用最广泛的。当然,如果为了扩展性考虑,也可以把NVMe overTCP/IP over 以太网,或者NVMe over RDMA over 以太网/IB,或者NVMe Over FC等等。

            底层接口,同样是手电筒,有人用灯丝灯泡的,有人用led的,有人用袖珍的,有人用手提的,有人用头戴的。这就是接口不同,但是它们传递的信息编码、物理层,都是一样的。比如,PCIE可以用标准插槽,也可以用自定义的插槽,但是里面的信号针脚数量都是一样的。

    三.各类存储系统使用的协议及接口一览

            存储系统中的硬件物理接口,包括:

    1.      SCSI 协议及接口 :最原始的上层协议及底层接口标准。有人可能蒙掉了,SCSI不是上层协议的名字么,为何底层物理接口也叫SCSI?因为SCSI这个标准最早的时候把上层协议一直到底层传输协议、网络层、物理层全给定义了。下图就是SCSI体系设备侧的接口物理形态。目前已被淘汰。其定义了:表示层到物理层。


    2.      IDE 协议及接口 :承载ATA协议。面向消费级,与SCSI接口处于同一个时代。同属并行总线接口,最大接2个设备。物理层速率比同时代SCSI接口低。目前已被淘汰。其定义了:传输层到物理层


    3.      FC 协议及接口 :用于存储系统时则承载SCSI协议,理论上可以承载任何上层协议。分为FCAL和FC Fabric两种网络层拓扑。磁盘接入的是FCAL拓扑。物理层接口如下图所示。为了满足企业级对可用性的要求,FC盘被作为双数据接口,接入两个成环器再各自上联到FC控制器上。图中所示的接口中包含两套数据针脚。其定义了:传输层到物理层


    4.      SATA 协议及接口 :仅用于承载ATA协议。其用于取代IDE接口。属于串行总线,每个通道只能接入一个设备,采用特殊的Mux可以复用多个设备。下图中左侧为数据口,右侧为供电口。数据口有三根地线和两对差分线。供电口有不同电流的多路冗余供电。其定义了:传输层到物理层


    5.      SAS 协议及接口 :在存储系统中用来取代FCAL接口。目前速率为12Gb/s,支持交换式组网,电路交换,不能成环。其定义了:传输层到物理层。SAS和SATA的连接器看上去差不多,仔细观察会发现SATA连接器中间的缺口在SAS上是被补平的,其反面其实还有7根数据线,这就是企业级冗余所要求的双端口,这第二个数据口接入到第二个SAS控制器或者Expander上。


    6.      PCIE 协议及接口 :承载PCIE传输协议。其可承载各种上层协议。用于存储系统时,一般直接承载NVMe协议,也可以承载SCSI协议,但是后者没有普及。其定义了:传输层到物理层。目前PCIE设备侧连接器形态主要是标准插槽或者SFF8639(U.2)。


    7.      emmc 协议及接口 :没有连接器,直接从flash颗粒管脚以贴片的方式与emmc控制器的管脚相连。承载emmc上层协议(与ATA/SCSI/NVMe处于同一个阶层)。底层物理层采用并行总线。emmc与早期scsi的做法类似,从顶层协议到底层物理层全都定义了一套自己的标准。其定义了:表示层到物理层


    8.      ufs 协议及接口 :没有连接器,直接从flash颗粒管脚以贴片的方式与ufs控制器的管脚相连。底层物理层采用串行总线。上层协议采用ufs协议(与ATA/SCSI/NVMe/emmc处于同一个阶层)。ufs与早期scsi的做法类似,从顶层协议到底层物理层全都定义了一套自己的标准。其定义了:表示层到物理层



    三. 连接器

            上述的SCSI、FC、SAS等各种协议都相应定义了自己的物理层连接器形态。但这并不意味着某种连接器只能承载当初定义它的那个协议。比如,SATA连接器可以承载以太网物理层信号,RJ45连接器可以承载串行通信协议物理层信号。SAS协议定义的HD miniSAS连接器可以承载PCIE物理层信号,等等。有个原则就是,为高速率传输协议定义的连接器,可以承载低速率传输协议,反之则不行。

     

    1.       上述各种协议原生定义的连接器,不再多描述。


    2.       SAS 方面,由于引入了Expander,外置端口形态在早期比较多,但是到12Gb速率时代之后,逐渐统一成HD miniSAS类型的连接器,如下图所示,分内口和外置口两个版本。miniSAS逐渐不再用。



    3.       U.2 连接器(SFF8649连接器),其中包含SAS、SATA和PCIE x4三套接口,充分利用空间,将三套金手指信号做到接口上,各干各的。意味着可以插入一块SAS或SATA或PCIE盘。样子乍一看和SAS差不多,但是别搞混了,还是有差别的。U.2实质上是一种combo组合接口。其定义了:连接器



    4.      M.2 连接器广泛用于平板电脑里的固态存储介质。其底层可承载PCIE传输协议,然后可以SCSI over PCIE,NVMe over PCIE。其也可以直接跑SATA信号



    总结一下:


    顶层协议

    传输层协议

    物理层接口/连接器

    端到端

    SCSI  

    ( 面向机械盘 )

    SCSI

    FC  

    SAS

    TCP(over  IP)

    RDMA oE/oIB

    TCP(over  IP)

    SCSI

    FC

    SAS

    Ethernet

    Infiniband

    SCSI  over SCSI over SCSI(Phased out)

    SCSI  over FC

    SCSI  over SAS

    SCSI  over TCP/IP over Ethernet (iSCSI)

    SCSI  over RDMA over IB(SRP)

    SCSI  over TCP/IP over IB

    NvMe

    ( 面向固态盘 )

    PCIE


     

     

    PCIe standard

    M.2

    SFF8639(U.2)

    NvMe  over PCIE over standard interface

    NvMe  over PCIE over M.2

    NvMe  over PCIE over SFF8639

    ATA

    (For PC Disk Drive)

    ATA

    SATA

    IDE

    SATA

    M.2

    ATA  over IDE(Phased out)

    ATA over SATA

    EMMC

    UFS

    EMMC

    UFS

    EMMC

    UFS

    full end to end, not overed to other transportation protocol yet

    (注:上表由热心网友yvonne.cai整理,特此致谢!)


    四.各类存储系统控制器/HBA一览

            通信是双方的,上文中大家看到的只是硬盘/外设一侧的接口形态,所有设备必须被接入到IO通道控制器上,比如IDE需要接入到IDE控制器,SATA盘需要接入到SATA控制器,SAS接入到SAS控制器,SCSI、PCIE等各自也都有各自的控制器。这些IO通道控制器在后端通过各自的连接器将1个、2个或者多个设备通过各自不同的总线方式挂接上,在前端则通过PCIE或者内部私有总线与系统IO桥相连,IO桥在通过更高速的总线连接到CPU。所以这类控制器又被称为总线适配器,如果将这类IO控制器做成一张板,插到PCIE槽上与IO桥相连,则称之为HostBus Adapter,HBA。当然,PCIE控制器是直接集成到CPU里的,PCIE设备是直接连接到CPU而不需要HBA,最多用个连接器转接板将CPU上的PCIEIO管脚连接到外部连接器或者插槽上。


    1.    SATA、IDE、PCIE、emmc、ufs这些协议的接口控制器,由于太过常用,一般都被集成到系统IO桥芯片中了。不需要转接到PCIE外扩出HBA来。


    2.    SCSI HBA


    3.    FC HBA


    4.    SAS HBA


    5.    以太网HBA


     

    6.    Infiniband HBA

    IB体系习惯把HBA叫做HCA(HostChannel Adapter)


     

    五.带Raid功能的HBA被称为Raid卡

            在HBA上增加或者增强对应资源,比如嵌入式CPU、板载DRAM、硬加速计算逻辑等,便可实现各种Raid了,此时HBA上报给OS的并不是其下挂的物理资源,而是经过Raid虚拟化之后逻辑资源。由于提升了并发性,增加了Write Back模式的缓存并加以电池或者超级电容保护,这些逻辑资源拥有更高的速度、更好的时延和更好的可靠性。


    1.  SCSIRaid卡


    2.  SATARaid卡


    3.  SAS Raid卡


     

    六. SAS/SATA硬盘、HBA、接入到服务器中的方式

            下图是最早期的SCSI硬盘的接入方式,由于采用总线结构,背板可以做成无源背板,而且走线十分方便,大部分导线被焊接到背板的PCB上,只留一个链接器连接到SCSI HBA/Raid卡即可。由于SCSI底层接口已经被淘汰,不多描述。


    1.    SAS卡直连无源背板形式 。该形式下,SAS卡(不管是HBA还是带Raid功能的HBA)采用x4的线缆直接连接到背板上的连接器,背板上每4个硬盘接口被导入到一个x4的连接器上从而直接连接到SAS卡。也就是说,如果有16块盘,那么背板需要出4个x4连接器,分别连接到SAS卡一侧的一个x4连接器上,前提是SAS卡必须支持对应数量的直连设备。目前Adaptec的12Gb SAS HBA可以单芯片最大直连16个SAS设备,为接入密度最大的产品。


    2.    SAS卡连接带Expander的有源背板形式 。有些型号的SAS卡最大只能直连8个设备,而有些服务器比如Dell R910,其前面板有12个硬盘槽位。此时,只能靠SAS Expander(简称EXP)了。12个槽位先连接到EXP上,EXP再出1个或者2个上行的x4口连接到HBA上。下图就是Dell R910的带SASEXP的背板。



    3.    SAS卡连接Expander子板再连接无源背板的形式 。有些时候服务器厂商不想为了增加一个Expander而再制作一款背板,而是想利用现有的无源背板,比如支持16盘位的无源背板,再加上一小块子板,将Expander放在这个子板上,再将这个子板与SAS HBA及背板分别连接起来。下图是Dell R730服务器的硬盘连接部分的俯视图。可以看到那块黄色的子卡,其背面有一块SAS Expander芯片,北向采用4个x4接口连接到SAS HBA,南向采用连接器与无源背板相连。


    4.    SAS卡直连设备无背板形式 。这种形式下,SAS/SATA盘直接放到服务器托架上,比如PC机,不提供背板。此时需要使用1分4的线缆,x4那头接到SAS卡上,分出来的4个数据口分别接一个SAS/SATA设备。 1分4的线缆如下图所示。


    5.    SAS连接到服务器机箱外置的JBOD形式 。这种形态并无本质上的变化,只是要求HBA提供外置接口,用外置线缆,硬盘和背板放到单独的箱子中。一般JBOD上的背板都是带Expander的,这样可以只保留一两个上行接口即可。



    七. NVMe固态盘、PCIE转接卡、PCIE交换芯片接入到服务器中的方式


    1.    全Combo形式 。如下图,24个插槽均为SFF8639也就是U.2接口,这就意味着不管是插SATA/SAS还是NVMe SSD到任何一个槽位,混差,数量配比不限,系统都可以识别到对应的硬盘,也就是所谓三模式(Tri-mode)。所以,每个接口必须将对应的金手指触点真的连接到对应的控制芯片上,如下图,每个插槽均连接SAS信号到SAS HBA以及PCIE信号到PCIE Switch芯片。这样做的成本当然是非常高的。


    2.    只有固定槽位支持全Combo盘的形式 。如下图,同样是这24个插槽,同样均为SFF8639也就是U.2接口,但是只有最后的4个槽位同时支持三模式Tri-mode,其余的20个槽位只支持SAS/SATA盘。


    3.    只有固定槽位支持NVMe盘的形式 。为了进一步节省成本,服务器厂商还可以让少数几个槽位只支持NVMe固态盘而不支持SAS/SATA,虽然依然是U.2接口,上面依然有对应的SAS/SATA的金手指信号,但是这些信号是被空置在那里的,没有连接任何上游的芯片。只有PCIE对应的针脚会被连接到上游芯片。而由于只有比如2个、4个NVMe Only的槽位,按照每个NVMe固态盘使用x4 Lane的PCIE接口的话,4个盘共需要16个Lane,可以将这16个Lane对应的金手指信号直接连接到CPU,也就是连接到主板上的一个x16的槽位上。所以,需要一块连接器转接卡先插到主板的x16 PCIE插槽上,转接板下游再出4个x4的miniSAS或者HD miniSAS连接器,然后用线缆连接到该连接器,线缆另一端再与硬盘背板上对应的miniSAS或者HDminiSAS连接器相连,这样就是下图所示的拓扑了。

    该服务器是一台戴尔服务器上的第一代 Express Flash PCIe SSD,以及PCIe 2.0的转接卡。散热片下面的是一块信号Repeter/Relay,其内部就是大量的三态缓冲门,为了增强信号质量,增强信号电流。


     

    八.Dell R930服务器的硬盘连接方式简析

            Dell R930服务器是一台最大支持4路CPU,提供最大24盘位的高端服务器。在硬盘配置方面,其提供了3个不同的背板,4盘位SAS/SATA背板,24 SAS/SATA盘位背板,以及16 SAS/SATA盘位+8 NVMe固态盘位背板。下面我们就来说说最后这种SAS和NVMe混布的选择。

            下图就是配置了该背板的服务器前视图。可以看到竖插的12块SAS/SATA盘和左右两边最下方的各两块横插的SAS/SATA盘;以及左右两边上方的各4块NVMe固态盘。


            对于NVMe盘位,其采用了NVMe Only的方式而不是Combo方式,也就是说这8个NVMe插槽只有PCIE信号被接入了系统中,SAS信号空置。如下图所示,可以看到每一边的4个U.2插槽上的x4 PCIE Lane信号被分别连接到一个HDminiSAS连接器,两边各4个。再采用对应的线缆连接到分别连接到一块PCIE连接器转接卡上,插入到主板的x16插槽中。


            下图中可以看到这两块PCIE连接器转接卡的样子,其插在了服务器的最后方。


            可以看到散热片下面的信号中继芯片,以及右侧的对应的4个HDminiSAS连接器。


            Dell R930服务器在前部还提供了一个特殊的托架,这个托架中可以安置两块子板,每个子板上有一片SAS Expander。由于戴尔R930配备的SAS HBA/Raid卡最大只能支持8盘直连,所以当配置的SAS硬盘数量大于8块时,必须增加SASExpander。该Expander子板采用连接器的方式与背板相连,从而与硬盘信号对接,上游提供对应的HDminiSAS连接器,通过线缆连接到其PERC9 Raid卡上。该托架可放置两块Expander子板,这样就可以将所有SAS/SATA硬盘分两部分分别接入到其中一块Expander,提升SAS链路的并发度。同时,R930支持插两块PERC9 Raid卡,那就可以分别接一块Expander子卡,进一步提升存储系统性能了。  


    最后,还有一种利用PCIE Switch将存储部分接入系统的方案,比如,在Dell PowerEdge FX2平台上,就使用了支持Partition功能的双PCIE Switch,具体可以参考冬瓜哥的另一篇文章: PCIE交换芯片及在戴尔PowerEdge FX2平台上的应用》



         声明:只要在本页面底部赞赏 2元或以上 者,冬瓜哥便将本文中的配图PPT原稿推送给你,每天晚上在公众号上统一对已打赏的朋友推送原稿。来吧,兄弟们!!


    展开全文
  • 电子邮件协议有哪些?哪几种

    万次阅读 2021-04-09 19:17:17
    电子邮件协议有哪些?哪几种 邮件服务器是一种Internet服务软件产品,支撑着Internet众多网络服务的是各种服务协议。在选择邮件服务器产品时,要重点考虑其支持服务协议方面的能力,因为它是衡量产品性能的重要指标...

    电子邮件协议有哪些?有哪几种
    邮件服务器是一种Internet服务软件产品,支撑着Internet众多网络服务的是各种服务协议。在选择邮件服务器产品时,要重点考虑其支持服务协议方面的能力,因为它是衡量产品性能的重要指标。与邮件服务器产品有关的网络服务协议主要有以下6个,其中我们重点介绍和我们关系最密切的两个:
    1.SMTP协议
      SMTP协议(Simple Mail Transfer Protocol,简单邮件传输协议)是最早出现的,也是被普遍使用的最基本的Internet邮件服务协议。正如它的名称,SMTP协议支持的功能确实比较简单,并且有安全方面的缺陷。经过它传递的所有电子邮件都是以普通正文形式进行的。它不能够传输诸如图像等非文本信息。在网络上明码传输文本信息意味着任何人都可以在中途截取并复制这些邮件,甚至对邮件内容进行窜改。邮件在传输过程中可能丢失。别有用心的人也很容易以冒名顶替的方式伪造邮件。为了克服上述缺陷,后来出现了ESMTP (Extended SMTP,扩展的SMTP协议)。
    2.POP3协议
      POP协议(Post Office Protocol,邮局协议)是一种允许用户从邮件服务器收发邮件的协议。它有2种版本,即POP2和POP3,都具有简单的电子邮件存储转发功能。POP2与POP3本质上类似,都属于离线式工作协议,但是由于使用了不同的协议端口,两者并不兼容。与SMTP协议相结合,POP3是目前最常用的电子邮件服务协议。
      POP3除了支持离线工作方式外,还支持在线工作方式。在离线工作方式下,用户收发邮件时,首先通过POP3客户程序登录到支持POP3协议的邮件服务器,然后发送邮件及附件;接着,邮件服务器将为该用户收存的邮件传送给POP3客户程序,并将这些邮件从服务器上删除;最后,邮件服务器将用户提交的发送邮件,转发到运行SMTP协议的计算机中,通过它实现邮件的最终发送。在为用户从邮件服务器收取邮件时,POP3是以该用户当前存储在服务器上全部邮件为对象进行*作的,并一次性将它们下载到用户端计算机中。一旦客户的邮件下载完毕,邮件服务器对这些邮件的暂存托管即告完成。使用POP3,用户不能对他们贮存在邮件服务器上的邮件进行部分传输。离线工作方式适合那些从固定计算机上收发邮件的用户使用。
      当使用POP3在线工作方式收发邮件时,用户在所用的计算机与邮件服务器保持连接的状态下读取邮件。用户的邮件保留在邮件服务器上。
    3.IMAP4协议(Internet Message Access Protocol,Internet消息访问协议)
      为用户提供了有选择地从邮件服务器接收邮件的功能、基于服务器的信息处理功能和共享信箱功能。
    4.HTTP协议和HTML语言
      支持这个协议的邮件服务器可以提供基于Web的电子邮件收发服务。借助HTML语言,管理员可以自己定义和编写面向用户的电子邮件服务网页。这样,用户可以使用任何Web浏览器,通过Internet在任何地点收发电子邮件。系统管理员也可以使用Web浏览器,实现对邮件服务器的远程管理*作。
    5.MIME协议
      多用途Internet邮件扩展(Multipurpose Internet Mail Extensions)协议。作为对SMTP协议的扩充,MIME规定了通过SMTP协议传输非文本电子邮件附件的标准。
    6.LDAP协议
      轻量目录访问协议(Lightweight Directory Access Protocol)。通过将相关的内容存放在统一的目录之下,目录服务为用户提供了基于客户/服务器工作方式的信息查询手段。

    展开全文
  • Java数据库连接协议JDBC学习

    千次阅读 2019-01-13 16:09:14
    由于不同的数据库操作数据的底层协议不同,因此不同的数据库厂商会提供对应的数据库驱动,比如mysql提供给Java的驱动mysql-connection-java-xxx.jar, oracle提供给Java的驱动ojdbcxx.jar,sqlserver提供给Java...

    什么是JDBC?

    Java的官方文档是如下描述的

    The JDBC API is the industry standard for database-independent connectivity between the Java programming language and a wide range of databases. The JDBC API provides a call-level API for SQL-based database access. JDBC technology allows you to use the Java programming language to exploit "Write Once, Run Anywhere" capabilities for applications that require access to enterprise data.

    JDBC API是独立的数据库连接工业标准协议,这个数据库连接指的是Java编程语言和各种各样数据库的连接。JDBC API提供了通过SQL语言获取数据的一套可调用接口API。JDBC技术允许开发者在开发企业数据获取的应用中,使用JAVA语言来实现“一次写入,多地运行”的能力。

    就我的理解而言,JDBC是Java用来实现各种各样数据库连接的一套标准化接口协议。JDBC API定义了如何获取/修改数据库中的数据。由于不同的数据库操作数据的底层协议不同,因此不同的数据库厂商会提供对应的数据库驱动,比如mysql有提供给Java的驱动mysql-connection-java-xxx.jar, oracle有提供给Java的驱动ojdbcxx.jar,sqlserver有提供给Java的驱动sqljdbcxx.jar等等。当然,这些数据库厂商也有提供给其他编程语言的数据库连接驱动,比如mysql提供给c++的驱动mysql-connector-c++-8.0.13-macos10.14-x86-64bit.dmg等等。而这些驱动会实现JDBC API,将其转化成对应数据库协议,从而实现了对数据的操作。

    JDBC整体架构

    JDBC API包含两个主要的接口集合: 第一个就是为应用写数据者提供的JDBC API, 第二个就是为驱动写数据提供的更底层的JDBC驱动API. 应用可以通过JDBC API获取数据,通过基于JAVA JDBC技术实现的驱动,如下图所示

    左边这条线路表示驱动会把JDBC的接口调用转换成关系型数据库所使用的网络协议,允许一个来自客户端机器的数据调用直接传递给对应的关系型数据库服务器,同时提供内部网的解决方案。
    右边这条线路则表示驱动会将JDBC的调用转换成中间件供应商的协议,中间件服务器再将中间件的协议转换成关系型数据库的协议。中间件提供了对很多数据库的连接。

    JDBC API

    1.Driver接口

    在操作数据库中的数据之前,先要加载对应的数据库驱动,如加载mysql对应的数据库驱动示例代码如下:Class.forName("com.mysql.jdbc.Driver");

    2.Connection接口

    加载完驱动后,就要从驱动管理器获取一个数据库的连接,通过这个连接完成数据库的数据操作,示例代码如下:Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");

    该接口常用的方法有

    •  createStatement():创建向数据库发送sql的statement对象。
    •  prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
    •  prepareCall(sql):创建执行存储过程的callableStatement对象。
    •  setAutoCommit(boolean autoCommit):设置事务是否自动提交。
    •  commit() :在链接上提交事务
    •  rollback() :在此链接上回滚事务
    •  close() : 关闭连接,释放资源

    3. Statement接口

    该接口主要用于SQL的执行,PreparedStatement和CallableStatement都继承该接口,这三种用于执行SQL语句的接口区别如下

    • Statement 主要用于简单数据的查询,不带参数
    • PreparedStatement用于带参数的查询,PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入,所以一般的应用开发都是用此接口来实现SQL查询
    • CallableStatement 用于存储过程的查询

    4. ResultSet接口

    主要是SQL查询结果的封装,用来实现数据的查询的处理。

    DataSource

    javax.sql.DataSource接口是JDBC 2.0 API中新出现的接口,该接口提供了另一种获取数据源的方式。在实际的应用开发中更建议使用DataSource来获取连接,而不建议通过DriverManager来获取连接。这样应用程序的代码变得可移植和易于管理,不用在程序里硬编码数据库的连接地址。另外,DataSounce对象可以提供连接池和分布式事务,必要的企业级数据计算,而这些功能的具体实现对于应用开发者来说是透明的。

    JNDI数据源

    应用程序常常部署在服务器中,如Tomcat这样的Web容器。这些服务器允许开发人员配置通过JNDI来获取数据源,这样的好处是数据源完全在应用程序之外进行管理,应用程序只要专注于数据的操作就好了。其次,这些应用服务器通常是以数据池的形式管理数据源,从而具备更好的性能。如下图所示(来自https://blog.csdn.net/zhanglf02/article/details/76726702),Web服务器上保存着一个数据库的多个连接。一个数据源dataSource的配置对应一个数据池。每个配置的DataSource被绑定在了JNDI树上(每个dataSource的配置都有一个唯一名称与之对应)客户端通过名称找到在JNDI树上绑定的DataSource,再由DataSource找到一个连接。

    è¿éåå¾çæè¿°

    主要的开源的数据源连接池(https://blog.csdn.net/qq_25406669/article/details/80222376

    • DBCP框架
    • C3P0框架
    • Druid框架

    DBCP是由Apache开发的一个Java数据库连接池项目,Tomcat使用的连接池组件就是DBCP。预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统。

    C3P0是开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。单线程,性能较差,适用于小型系统。

    Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上。

    Spring配置数据源

    • 配置JNDI数据源
    • 配置连接池数据源
    • 自定义的数据源

    JNDI数据源配置

    位于jee命名空间下的<jee:jndi-lookup>元素可以用于检索JNDI中的任何元素,并将其作为Spring的bean。简要的配置示例如下:

    <jee:jndi-lookup id="dataSource"
         jndi-name="/jdbc/SplitterDS"
         resource-ref="true"/>

    或者如下配置

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> 
             <property name="jndiName"> 
             <value>java:comp/env/jdbc/roseindiaDB_local</value></property> 
    </bean> 

    jndi-name就是上文中讲到的datasource配置文件中的names属性,如果应用程序部署在web应用服务器中,需要将resource-ref为true,这样jndi-name将会自动添加“java:comp/env/”前缀。

    数据源连接池配置 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
                  <property name="driverClassName"> 
                         <value>oracle.jdbc.driver.OracleDriver</value> 
                  </property> 
                  <property name="url"> 
                         <value>jdbc:oracle:xxxx</value> 
                  </property> 
                  <property name="username"> 
                         <value>test</value> 
                  </property> 
                  <property name="password"> 
                         <value>test</value> 
                  </property> 
                  <property name="maxActive"> 
                         <value>255</value> 
                  </property> 
                  <property name="maxIdle"> 
                         <value>2</value> 
                  </property> 
                  <property name="maxWait"> 
                         <value>120000</value> 
                  </property> 
     </bean> 

    Spring实现的基于JDBC驱动的数据源

    • DriverManagerDataSource: 每个连接请求时返回一个新建的连接
    • SimpleDriverDataSource: 跟DriverManagerDataSource工作方式类似,但是它直接使用JDBC驱动来解决特定环境的类加载问题
    • SingleConnectionDataSource: 每个连接请求的时候返回同一个连接,并不是严格意义上的连接池
    展开全文
  • 本文档的主要内容详细介绍的是网络存储技术的存储协议详细说明包括了:1.了解各种存储协议,2.了解各种存储协议的主要区别,3.iSCSI协议存储未来的发展之路。   SCSI(Small Computer System Interface,...
  • 本文主要内容: DAS存储; NAF存储; SAN存储; 三种存储区别; FTP工作原理
  • TCP是面向连接的、可靠的进程到进程通信的协议。它提供的是全双工(双向可传输)的服务,每个TCP都发送缓存和接受缓存,用来临时存储数据。 1、TCP报文段: TCP把若干个字节构成一个分组,称为报文段(segment)。...
  • 数据的存取需求时,数据可以通过存储区域网络在服务器和后台存储设备之间高速传输。 IP SAN:通过百兆/千兆/万兆以太网络连接应用服务器和后端存储系统。将SCSI指令和数据块通过高速以太网传输,继承以太网的...
  • 蓝牙电话之PBAP协议连接

    千次阅读 2020-04-10 10:27:33
    前一篇文章《蓝牙电话之PBAP协议分析》大致讲解了PBAP协议的相关内容,本篇我们就开启PBAP连接流程的分析。由于PBAP的连接过程涉及到的知识点较多,有些地方没有分析写出来还忘理解。 PBAP的连接分为连接请求和连接...
  • 1.1存储协议及技术.pdf

    2020-06-06 12:18:08
    存储协议及技术 SCSI(Small Computer System Interface,小型计算机系统接口) 最初是一种为小型机研制的接口...连接  SCSI协议是主机不存储磁盘通信的基本协议  DAS使用SCSI协议实现主机服务器不存储设备的互联。
  • 2、PCI和PCI-E都为北桥区,区别在于前者并行口,后者为串行口,多通道增强了数据稳定性和传输频率提升(并行的多路复用因干扰性对频率限制);另外还有PCI-X,不过使用并不广泛; 3、PCI-E又分×1、×4、×8、×...
  • NAS(Network Attached Storage)协议

    千次阅读 2019-10-18 14:11:42
    先来看一道面试题:NFS 和 SMB 是最常见的两种 NAS(Network Attached Storage)协议,当把一个文件系统同时通过 NFS 和 SMB 协议共享给多个主机访问时,以下哪些说法是错误的:(多选) A. 不可能这样的操作,即...
  • 您可以使用Neo4j Bolt协议的Database Toolbox:trade_mark:接口与Neo4j:registered:数据库中存储的图形数据进行交互。 Neo4j Bolt协议的数据库工具箱接口使用Bolt协议进行连接。Neo4j的MATLAB接口使您能够: *使用...
  • 设备终端接入协议EDP协议(v1.6版本),很详细。 目录 Enhanced Device Protocol(EDP) 1 1 说明 2 2 设备与业务接入模式 2 3 接入流程 3 4 消息格式 3 4.1 消息类型 3 4.2 剩余消息长度 4 4.3 选项 5 4.4 消息体 5...
  • 高清、长周期呈现海量存储需求 高清已经在安防行业全面铺开应用。除了带给用户能够看得更清的良好视觉感受外,对...存储周期方面,现在也了政府的有力推动。对当前整个安防市场来讲,特别是大公安、大交通、楼宇...
  • 要明白,这句话的含义是指在说明,http协议作为技术背景的web应用程序请求——应答模式是无状态的,这个事实基本不会发生改变,也不会因为加入cookies、session机制而变成状态的。要明白,这种前后因果关系:...
  • 因特网使用的IP协议是无连接的,因此其传输是不可靠的。这样容易使人们感到因特网很不可靠,那为什么当初不直接把它设计为可靠的?先打一个比方。邮局寄送的平信很像无连接的IP数据报。每封平信可能走不同的传送路径...
  • 工作上转发程序,从一个客户端发送数据到转发程序再发送到另一个服务端。整个传输协议是基于交通部809协议要求的。 809协议文档:(https://download.csdn.net/download/qq_28198181/10920681) 目录 问题1:...
  • 02硬盘接口及协议存储介绍

    千次阅读 2018-08-31 18:01:36
    通讯协议 一、SCSI 二、FC(光纤通道) 三、iSCSI 四、iSCSI和FC的比较 三种常见的存储类型 硬盘接口类型 一、 IDE磁盘 IDE(Integrated Drive Electronics), 本意是指把控制器与盘体集成...
  • HTTP协议之:TCP连接详解

    千次阅读 2015-12-25 18:30:15
    TCP连接HTTP请求连接过程HTTP是一个应用层的协议,在这个层的协议,是一种网络交互需要遵守的一种协议规范。 1. 浏览器解析出主机名 2. 浏览器查询这个主机名的IP地址(DNS) 3. 浏览器获得端口号 4. 浏览器发起到...
  • HTTP协议学习笔记---HTTP持久连接和如何正确地关闭HTTP连接 一,持久连接 什么是持久连接?对于HTTP协议而言,它是基于请求响应模型,Client向Server发请求时,先建立一条HTTP连接,Server给Client响应数据...
  • 继上篇MQTT测试环境搭建后,接下来趁热打铁来分析MQTT通讯协议数据包,来加深对MQTT理解,因个人技术有限,若以下分析误,望留言纠正,谢谢。 环境: MQTT服务器(Mosquitto,ubuntu) + MQTT客户端(paho, windows...
  • 在jdk1.6下工作比较好, smi-s协议采集数据的话,可以用这个客户端查看数据。
  • HTTP协议之无连接与无状态

    千次阅读 2018-08-02 10:56:12
     HTTP协议一共五大特点,1、支持客户/服务器模式;2、简单快速;3、灵活;4、无连接;5、无状态。其中无状态是其中主要特点之一。因此,常说HTTP是一个无状态协议。所谓的无状态是指协议对于事务处理没有记忆能力...
  • DNS解析的过程就是寻找哪台机器上你需要资源的过程。当你在浏览器中输入一个地址时,例如www.baidu.com,其实不是百度网站真正意义上的地址。互联网上每一台计算机的唯一标识是它的IP地址,但是...
  • 在正式给大家介绍自定义协议之前,我们先对网络传输和协议解析的相关知识点做一个基本的介绍,尽管这些知识点我们在学校里学过,但难免会有所遗忘,这里先做一个简单的介绍,以便对后文的内容理解更加顺畅。...
  • 以太网三种存储协议

    千次阅读 2012-09-10 16:09:17
    以太网三种存储协议之间的选择...在以太网上运行文件访问没有多少争议,但是块协议三种协议在互相竞争。 关键词: AoE 光纤通道 FCoE iSCSI DOSTOR存储在线8月23日国际报道:未来,所有的存储网络
  • 一、TCP协议 TCP协议提供的服务 ... TCP协议连接过程(三次握手、四次断开) 二、UDP协议 UDP协议提供的服务 UDP协议的报文段 三、TCP与UDP的区别 四、TCP与UDP常用的端口以及端口号 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 459,007
精华内容 183,602
关键字:

存储连接有哪些协议