玩转亚马逊 AWS IoT(3): SpringBoot 2.7 集成 AWS IoT 服务
文章目录
- 1 AWSIoT 开发者文档集合
- 2 核心 Maven 依赖
- 3 IoT 配置信息
- 4 核心代码
- 4.1 服务端
- 4.2 设备端
- 4.2.1 MQTT 消息推送类
- 4.2.2 MQTT 消息监听类
- 4.2.3 设备端操作工具类
- 5 测试
- 6 推荐参考文档
- 7 Github 源码
1 AWSIoT 开发者文档集合
Amazon IoT Core 开发人员指南(设备端)
Amazon IoT Device SDK(设备端)
AWS IoT Core API 参考(服务端)
AWS SDK for Java 2.0(服务端)
服务端主要是定义 IoT相关的权限、物品类型、物品等功能;设备端主要是收发MQTT消息功能
准备工作:
玩转亚马逊 AWS IoT(1): IoT 业务梳理
玩转亚马逊 AWS IoT(2): IoT 控制台使用与开发操作文档
2 核心 Maven 依赖
./demo-aws-iot/pom.xml
<!-- AWS iot server sdk --><dependency><groupId>software.amazon.awssdk</groupId><artifactId>iot</artifactId><version>${aws-iot-server.version}</version></dependency><!-- AWS iot device sdk --><dependency><groupId>com.amazonaws</groupId><artifactId>aws-iot-device-sdk-java</artifactId><version>${aws-iot-sdk-device.version}</version></dependency>
其中依赖版本信息为:
<aws-iot-server.version>2.17.230</aws-iot-server.version><aws-iot-sdk-device.version>1.3.10</aws-iot-sdk-device.version>
3 IoT 配置信息
配置类
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/common/config/AwsIotAccountConfig.java
package com.ljq.demo.springboot.aws.iot.common.config;import lombok.Getter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;/*** @Description: 亚马逊 iot 服务账号配置类* @Author: junqiang.lu* @Date: 2022/7/25*/
@Getter
@ToString
@Configuration
public class AwsIotAccountConfig {/*** 终端节点*/@Value(value = "${aws.iot.clientEndpoint}")private String clientEndpoint;/*** 接入公钥*/@Value(value = "${aws.iot.accessKeyId}")private String accessKeyId;/*** 接入私钥*/@Value(value = "${aws.iot.secretAccessKey}")private String secretAccessKey;}
application.yml 配置
./demo-aws-iot/src/main/resources/application.yml
## aws iot config
aws:iot:clientEndpoint: xxxx.iot.cn-northwest-1.amazonaws.com.cnaccessKeyId: xxxxxsecretAccessKey: xxxxxxxx
4 核心代码
4.1 服务端
权限策略、证书、物品等操作工具类
工具类包含的 IoT操作方法: 创建物品类型、创建物品、创建证书、绑定物品与证书、创建策略、绑定证书与策略、更新策略
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/server/util/AwsIotServerClientComponent.java
package com.ljq.demo.springboot.aws.iot.server.util;import com.ljq.demo.springboot.aws.iot.common.config.AwsIotAccountConfig;
import com.ljq.demo.springboot.aws.iot.server.vo.CertificateVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.profiles.ProfileProperty;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iot.IotClient;
import software.amazon.awssdk.services.iot.model.*;
import software.amazon.awssdk.utils.StringInputStream;import java.util.Objects;/*** @Description: AWS iot 服务端工具类* @Author: junqiang.lu* @Date: 2022/7/21*/
@Slf4j
@Component
public class AwsIotServerClientComponent {private AwsIotServerClientComponent(){}@Autowiredprivate AwsIotAccountConfig iotAccountConfig;private IotClient iotClient;/*** 初始化 iot 客户端** @return*/@Bean(value = "iotServerClient")public IotClient iotClient() {StringBuilder cfgBuilder = new StringBuilder("[default]\n");cfgBuilder.append(ProfileProperty.AWS_ACCESS_KEY_ID).append(" = ").append(iotAccountConfig.getAccessKeyId()).append("\n");cfgBuilder.append(ProfileProperty.AWS_SECRET_ACCESS_KEY).append(" = ").append(iotAccountConfig.getSecretAccessKey()).append("\n");ProfileFile profileFile = ProfileFile.builder().content(new StringInputStream(cfgBuilder.toString())).type(ProfileFile.Type.CONFIGURATION).build();AwsCredentialsProviderChain awsCredentialsProviderChain = AwsCredentialsProviderChain.of(ProfileCredentialsProvider.builder().profileFile(profileFile).build());if (Objects.isNull(iotClient)) {synchronized (AwsIotServerClientComponent.class) {if (Objects.isNull(iotClient)) {iotClient = IotClient.builder().credentialsProvider(awsCredentialsProviderChain).region(Region.CN_NORTHWEST_1).build();}}}return iotClient;}/*** 创建物品类型** @param thingType 物品类型*/public boolean createThingType(String thingType) {Tag tag = Tag.builder().key("type").value(thingType).build();CreateThingTypeRequest request = CreateThingTypeRequest.builder().thingTypeName(thingType).tags(tag).build();CreateThingTypeResponse response = iotClient.createThingType(request);return response.sdkHttpResponse().isSuccessful();}/*** 创建物品** @param thingName 物品名称* @param thingType 物品类型* @return*/public boolean createThing(String thingName, String thingType) {CreateThingRequest request = CreateThingRequest.builder().thingName(thingName).thingTypeName(thingType).build();CreateThingResponse response = iotClient.createThing(request);return response.sdkHttpResponse().isSuccessful();}/*** 创建证书** @return*/public CertificateVo createCert() {CreateKeysAndCertificateRequest request = CreateKeysAndCertificateRequest.builder().setAsActive(true).build();CreateKeysAndCertificateResponse response = iotClient.createKeysAndCertificate(request);if (response.sdkHttpResponse().isSuccessful()) {CertificateVo certVo = new CertificateVo();certVo.setCertificateArn(response.certificateArn());certVo.setCertificateId(response.certificateId());certVo.setCertificatePem(response.certificatePem());certVo.setPublicKey(response.keyPair().publicKey());certVo.setPrivateKey(response.keyPair().privateKey());return certVo;}return null;}/*** 绑定物品与证书** @param certArn 证书资源唯一标识* @param thingId 物品 ID* @return*/public boolean bindThingAndCert(String certArn, String thingId) {AttachThingPrincipalRequest request = AttachThingPrincipalRequest.builder().thingName(thingId).principal(certArn).build();AttachThingPrincipalResponse response = iotClient.attachThingPrincipal(request);return response.sdkHttpResponse().isSuccessful();}/*** 创建策略** @param policyName 策略名称* @param policyContent 策略内容(json 格式)* @return*/public boolean createPolicy(String policyName, String policyContent) {CreatePolicyRequest request = CreatePolicyRequest.builder().policyName(policyName).policyDocument(policyContent).build();CreatePolicyResponse response = iotClient.createPolicy(request);return response.sdkHttpResponse().isSuccessful();}/*** 绑定证书与策略** @param certArn* @param policyName* @return*/public boolean bindCertAndPolicy(String certArn, String policyName) {AttachPolicyRequest request = AttachPolicyRequest.builder().policyName(policyName).target(certArn).build();AttachPolicyResponse response = iotClient.attachPolicy(request);return response.sdkHttpResponse().isSuccessful();}/*** 更新策略** @param policyName* @param policyContent* @return*/public boolean updatePolicy(String policyName, String policyContent) {// 查询策略的所有版本ListPolicyVersionsRequest listPolicyVersionsRequest = ListPolicyVersionsRequest.builder().policyName(policyName).build();ListPolicyVersionsResponse listPolicyVersionsResponse = iotClient.listPolicyVersions(listPolicyVersionsRequest);if (!listPolicyVersionsResponse.sdkHttpResponse().isSuccessful()) {log.warn("删除策略失败,查询策略列表出错");return false;}if (CollectionUtils.isEmpty(listPolicyVersionsResponse.policyVersions())) {log.warn("删除策略失败,策略列表为空");return false;}// 删除非活跃版本listPolicyVersionsResponse.policyVersions().forEach(version -> {if (!version.isDefaultVersion()) {DeletePolicyVersionRequest deletePolicyVersionRequest = DeletePolicyVersionRequest.builder().policyName(policyName).policyVersionId(version.versionId()).build();iotClient.deletePolicyVersion(deletePolicyVersionRequest);}});// 创建策略版本并设置为活跃状态CreatePolicyVersionRequest request = CreatePolicyVersionRequest.builder().policyName(policyName).policyDocument(policyContent).setAsDefault(true).build();CreatePolicyVersionResponse response = iotClient.createPolicyVersion(request);return response.sdkHttpResponse().isSuccessful();}}
4.2 设备端
4.2.1 MQTT 消息推送类
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/device/pubsub/IotPublisher.java
package com.ljq.demo.springboot.aws.iot.device.pubsub;import com.amazonaws.services.iot.client.AWSIotMessage;
import com.amazonaws.services.iot.client.AWSIotQos;
import lombok.extern.slf4j.Slf4j;/*** @Description: AWS iot 消息推送类* @Author: junqiang.lu* @Date: 2022/7/21*/
@Slf4j
public class IotPublisher extends AWSIotMessage {public IotPublisher(String topic, AWSIotQos qos, byte[] payload) {super(topic, qos, payload);}@Overridepublic void onSuccess() {log.info("[MQTT消息推送-Success]topic: {},data: {}",topic, getStringPayload());// 业务处理}@Overridepublic void onFailure() {log.info("[MQTT消息推送-Error]topic: {},data: {}",topic, getStringPayload());// 业务处理}@Overridepublic void onTimeout() {log.info("[MQTT消息推送-time out]topic: {},data: {}",topic, getStringPayload());// 业务处理}}
4.2.2 MQTT 消息监听类
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/device/pubsub/IotDemoListener.java
package com.ljq.demo.springboot.aws.iot.device.pubsub;import com.amazonaws.services.iot.client.AWSIotMessage;
import com.amazonaws.services.iot.client.AWSIotQos;
import com.amazonaws.services.iot.client.AWSIotTopic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;/*** @Description: AWS iot 主题监听类* @Author: junqiang.lu* @Date: 2022/7/21*/
@Slf4j
@Component
public class IotDemoListener extends AWSIotTopic {private static final String TOPIC = "hello/demo/xxx";public IotDemoListener() {super(TOPIC, AWSIotQos.QOS1);}@Overridepublic void onMessage(AWSIotMessage message) {String content = message.getStringPayload();log.info("message content: {}", content);// 业务处理}
}
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/device/pubsub/IotConnectEventListener.java
package com.ljq.demo.springboot.aws.iot.device.pubsub;import com.amazonaws.services.iot.client.AWSIotMessage;
import com.amazonaws.services.iot.client.AWSIotQos;
import com.amazonaws.services.iot.client.AWSIotTopic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;/*** @Description: AWS iot 设备上下线事件监听类* @Author: junqiang.lu* @Date: 2022/7/21*/
@Slf4j
@Component
public class IotConnectEventListener extends AWSIotTopic {private static final String TOPIC = "hello/demo/connect/event";public IotConnectEventListener() {super(TOPIC, AWSIotQos.QOS1);}@Overridepublic void onMessage(AWSIotMessage message) {String content = message.getStringPayload();log.info("设备上下线通知: {}", content);// 业务处理}
}
4.2.3 设备端操作工具类
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/device/util/AwsIotDeviceClientComponent.java
package com.ljq.demo.springboot.aws.iot.device.util;import com.amazonaws.regions.Regions;
import com.amazonaws.services.iot.client.AWSIotException;
import com.amazonaws.services.iot.client.AWSIotMqttClient;
import com.amazonaws.services.iot.client.AWSIotQos;
import com.amazonaws.services.iot.client.auth.Credentials;
import com.amazonaws.services.iot.client.auth.StaticCredentialsProvider;
import com.ljq.demo.springboot.aws.iot.common.config.AwsIotAccountConfig;
import com.ljq.demo.springboot.aws.iot.device.pubsub.IotConnectEventListener;
import com.ljq.demo.springboot.aws.iot.device.pubsub.IotDemoListener;
import com.ljq.demo.springboot.aws.iot.device.pubsub.IotPublisher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/*** @Description: AWS iot 设备端 MQTT 操作工具类* @Author: junqiang.lu* @Date: 2022/7/21*/
@Slf4j
@Component
public class AwsIotDeviceClientComponent implements ApplicationRunner {public AwsIotDeviceClientComponent(){}public static final String CLIENT_ID = "demo-server-202207";@Autowiredprivate AwsIotAccountConfig iotAccountConfig;private AWSIotMqttClient mqttClient;@Autowiredprivate IotDemoListener iotDemoListener;@Autowiredprivate IotConnectEventListener iotConnectEventListener;@Overridepublic void run(ApplicationArguments args) throws Exception {mqttClient.connect();log.info("aws mqtt server 客户端连接成功");// 主题订阅mqttClient.subscribe(iotDemoListener, true);mqttClient.subscribe(iotConnectEventListener, true);}@Bean(name = "awsIotMqttClient")public AWSIotMqttClient awsIotMqttClient() {log.info("创建 awsIotMqttClient bean");Credentials credentials = new Credentials(iotAccountConfig.getAccessKeyId(),iotAccountConfig.getSecretAccessKey());StaticCredentialsProvider credentialsProvider = new StaticCredentialsProvider(credentials);mqttClient = new AWSIotMqttClient(iotAccountConfig.getClientEndpoint(), CLIENT_ID, credentialsProvider,Regions.CN_NORTHWEST_1.getName());return mqttClient;}/*** 消息推送* @param topic* @param data* @throws AWSIotException*/public void pushMessage(String topic, byte[] data) throws AWSIotException {log.info("server topic={},>>> {}", topic, new String(data));mqttClient.publish(new IotPublisher(topic, AWSIotQos.QOS1, data));}}
5 测试
接口示例:
创建策略
POST
http://127.0.0.1:9000/api/iot/server/policy/create
请求参数:
{"policyName": "testPolicy","policyContent": "{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Action\": \"iot:Connect\", \"Resource\": \"arn:aws-cn:iot:cn-northwest-1:xxxxx:client/${iot:Connection.Thing.ThingName}\" }, { \"Effect\": \"Allow\", \"Action\": \"iot:Publish\", \"Resource\": \"arn:aws-cn:iot:cn-northwest-1:xxxxx:topic/hello/demo/xxx\" }, { \"Effect\": \"Allow\", \"Action\": \"iot:Subscribe\", \"Resource\": \"arn:aws-cn:iot:cn-northwest-1:xxxxx:topicfilter/hello/demo/client/${iot:Connection.Thing.ThingName}\" }, { \"Effect\": \"Allow\", \"Action\": \"iot:Receive\", \"Resource\": \"*\" } ] }"
}
其他接口参考源码:
服务端:
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/server/controller/IotServerDemoController.java
package com.ljq.demo.springboot.aws.iot.server.controller;import com.ljq.demo.springboot.aws.iot.server.param.*;
import com.ljq.demo.springboot.aws.iot.server.util.AwsIotServerClientComponent;
import com.ljq.demo.springboot.aws.iot.server.vo.CertificateVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;/*** @Description: iot 服务端示例控制层* @Author: junqiang.lu* @Date: 2022/7/25*/
@Slf4j
@RestController
@RequestMapping(value = "/api/iot/server")
public class IotServerDemoController {@Autowiredprivate AwsIotServerClientComponent iotClientComponent;/*** 创建策略** @param createPolicyParam* @return*/@PostMapping(value = "/policy/create", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> createPolicy(@RequestBody IotServerCreatePolicyParam createPolicyParam) {boolean flag = iotClientComponent.createPolicy(createPolicyParam.getPolicyName(),createPolicyParam.getPolicyContent());return ResponseEntity.ok(flag);}/*** 更新策略** @param updatePolicyParam* @return*/@PutMapping(value = "/policy/update", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> updatePolicy(@RequestBody IotServerUpdatePolicyParam updatePolicyParam) {boolean flag = iotClientComponent.updatePolicy(updatePolicyParam.getPolicyName(),updatePolicyParam.getPolicyContent());return ResponseEntity.ok(flag);}/*** 创建物品类型** @param createThingTypeParam* @return*/@PostMapping(value = "/thingType/create", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> createThingType(@RequestBody IotServerCreateThingTypeParam createThingTypeParam) {boolean flag = iotClientComponent.createThingType(createThingTypeParam.getThingTypeName());return ResponseEntity.ok(flag);}/*** 创建物品** @param createThingParam* @return*/@PostMapping(value = "/thing/create", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> createThing(@RequestBody IotServerCreateThingParam createThingParam) {boolean flag = iotClientComponent.createThing(createThingParam.getThingName(),createThingParam.getThingTypeName());return ResponseEntity.ok(flag);}/*** 创建证书** @param createCertParam* @return*/@PostMapping(value = "/cert/create", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> createCert(@RequestBody IotServerCreateCertParam createCertParam) {CertificateVo cert = iotClientComponent.createCert();return ResponseEntity.ok(cert);}/*** 绑定物品与证书** @param bindThingAndCertParam* @return*/@PostMapping(value = "/thing/cert/bind", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> bindThingAndCert(@RequestBody IotServerBindThingAndCertParam bindThingAndCertParam) {boolean flag = iotClientComponent.bindThingAndCert(bindThingAndCertParam.getCertArn(),bindThingAndCertParam.getThingName());return ResponseEntity.ok(flag);}/*** 绑定证书与策略** @param bindCertAndPolicyParam* @return*/@PostMapping(value = "/cert/policy/bind", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> bindCertAndPolicy(@RequestBody IotServerBindCertAndPolicyParam bindCertAndPolicyParam) {boolean flag = iotClientComponent.bindCertAndPolicy(bindCertAndPolicyParam.getCertArn(),bindCertAndPolicyParam.getPolicyName());return ResponseEntity.ok(flag);}
}
设备端:
./demo-aws-iot/src/main/java/com/ljq/demo/springboot/aws/iot/device/controller/IotDeviceDemoController.java
package com.ljq.demo.springboot.aws.iot.device.controller;import com.amazonaws.services.iot.client.AWSIotException;
import com.ljq.demo.springboot.aws.iot.device.param.IotDevicePublishParam;
import com.ljq.demo.springboot.aws.iot.device.util.AwsIotDeviceClientComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.nio.charset.StandardCharsets;/*** @Description: iot 设备示例控制层* @Author: junqiang.lu* @Date: 2022/7/22*/
@RestController
@RequestMapping(value = "/api/iot/device")
public class IotDeviceDemoController {@Autowiredprivate AwsIotDeviceClientComponent deviceClientComponent;@PostMapping(value = "/publish", produces = {MediaType.APPLICATION_JSON_VALUE})public ResponseEntity<Object> publish(@RequestBody IotDevicePublishParam publishParam) throws AWSIotException {String topic = "hello/demo/client/" + publishParam.getClientId();deviceClientComponent.pushMessage(topic, publishParam.getMessage().getBytes(StandardCharsets.UTF_8));return ResponseEntity.ok(System.currentTimeMillis());}}
6 推荐参考文档
Amazon IoT Core 开发人员指南(设备端)
Amazon IoT Device SDK(设备端)
AWS IoT Core API 参考(服务端)
AWS SDK for Java 2.0(服务端)
Amazon IoT 规则操作
IoT Events
Amazon IoT SQL 参考
MQTT 主题-主题筛选条件
生命周期事件
Amazon IoT Core 策略操作
Amazon IoT Core 策略示例
基本任务策略示例
7 Github 源码
Gtihub 源码地址 : https://github.com/Flying9001/springBootDemo
个人公众号:404Code,分享半个互联网人的技术与思考,感兴趣的可以关注.
玩转亚马逊 AWS IoT(3): SpringBoot 2.7 集成 AWS IoT 服务相关推荐
- Zadig 玩转亚马逊云科技全家桶
以下文章来源于 KodeRover 前言 亚马逊云科技提供全球覆盖广泛.服务深入的云平台,连续 11 年被 Gartner 评为"全球云计算领导者".其完整的云原生"家族 ...
- 玩转亚马逊 AWS IoT(1): IoT 业务梳理
文章目录 1 亚马逊 IoT 服务简介 2 账号与费用 2.1 IoT 服务费用 2.2 注册账号 3 亚马逊 IoT 系统关系图 4 亚马逊 AWS IoT 接入流程 5 IoT 网络交互图 1 亚 ...
- QCI宣布在亚马逊上推出即开即用的量子优化服务
量子计算公司 (QCI) 宣布其云量子应用加速器Qatalyst现可作为软件即服务 (SaaS) 在亚马逊平台上使用,适用于经典和量子计算机. 该SaaS服务无需复杂的量子编程,行业专家 (SMEs) ...
- kindle亚马逊个人文档不显示_Kindle个人文档服务
介绍通过Kindle个人文档服务,您可以免费将部分类型的文档直接发送至已注册至您的亚马逊Z.cn帐户的Fire平板电脑.Kindlle电子书阅读器和支持的Kindle阅读软件. 您可以通过授权的电子邮 ...
- 亚马逊云科技在中国区域新推多项服务;德州仪器携手台达打造高效能服务器电源供应器 | 全球TMT...
大公司动向 亚马逊云科技宣布,通过与光环新网和西云数据的紧密合作,近期在中国区域推出多项现代化应用相关服务及功能,包括满足客户本地数据中心容器运算需求的容器服务Amazon Elastic Conta ...
- 亚马逊云科技不断迭代,为客户提供更加优质的服务
2023年3月亚马逊云科技宣布Amazon Linux 2023(AL2023)正式发布.自2010年以来,亚马逊云科技一直提供云优化Linux发行版.此次发布的Amazon Linux 2023是第 ...
- aws php环境,亚马逊云介绍(3):使用AWS EC2搭建WEB服务器(LNMP) | 恋香缘
一.基本环境介绍 二.安装mysql 登录EC2后使用 sudo su 切换到root权限. 使用下面命令为下一步的安装做准备: apt-get update 安装mysql server和clien ...
- 傲娇亚马逊AWS与特色中国的四年大博弈
经过四年的艰辛历程,2016年9月7日,亚马逊旗下云计算服务平台(Amazon Web Services,下称AWS)宣布正式在中国商用.这家最早向世界提供云计算服务的公司,将它的全球第十个数据中心选 ...
- ESP32 AT指令连接AWS亚马逊云
ESP32 AT指令连接AWS亚马逊云 文章目录 ESP32 AT指令连接AWS亚马逊云 1. 概述 2. 相关资料及设备说明 3. AWS云平台接入 3.1 AWS云平台接入概述 3.2 接入AWS ...
- 美团配送和亚马逊AWS的异曲同工
5月6日,<美团正式发布新品牌,你猜是什么?>一文刷爆我的朋友圈和微信群,问题的答案是"美团配送",这是美团全新推出的品牌,旨在帮助各行各业的商家可以像云计算一样使用同 ...
最新文章
- 自家表兄弟Tomcat和Jetty
- user agent stylesheet对格式的影响
- asp.net访问sqlserver获取数据、IsPostBack属性和VS可视化调试的概念
- 【机器学习基础】重磅发布!吴恩达 AI 完整课程资源超级大汇总!
- leetcode-283-移动零
- Netweaver 服务器和客户端TLS版本号不匹配的解决方案
- 22 MM配置-采购-采购信息记录-定义编码范围
- winForm添加图标
- 外星网络大肆入侵,地球人能安好吗?
- 螺旋传动设计系统lisp_石狮螺旋输送机质量可靠
- fastdfs原理简析
- ABP框架系列之四十:(Notification-System-通知系统)
- GPT系列论文精读-GPT1
- 软工网络15团队作业9——项目验收与总结
- 纷享自定义函数:客户回填工商信息(天眼查)
- 怎样提高平面设计色彩表现力
- 2019互联网岳麓峰会”区块链分会场—长沙率先推出区块链公共服务平台
- 百度推广系列之广告词编写必杀技
- 单片机中的浮点数转换成串口可打印格式
- 在Excel中给不足位数的数字前面补0
热门文章
- RedHat上安装openssl
- android aidl oneway用法
- 《用户体验要素——以用户为中心的产品设计》读书笔记
- c++ primer kindle_kindle全系列使用墨水屏版微信读书解决方法,你的无限卡有用了...
- nas存储用网线直连服务器,NAS将存储设备通过标准的网络拓扑结构连接,无需服务器直接上网...
- 将RGB颜色转换成16bit颜色
- 找出连续最长数字串python_在Python中查找最长的连续字母和数字子字符串
- 编程题——真题训练一(WYYX)
- 如何制作PE系统盘?
- CAN学习笔记---负载率计算