Redis单机数据迁移至Sentinel集群
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.asdc</groupId>
<artifactId>multiRedisDatabase</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>multiRedisDatabase</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.16.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
application.properties
# Redis数据库索引(默认为0)
spring.redis.database=10
# Redis服务器地址
spring.redis.hostName=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=1024
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=200
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=15000 spring.redis.sentinel.master=mymaster spring.redis.sentinel.nodes=127.0.0.1,127.0.0.1,127.0.0.1
spring.redis.sentinel.port=26379
package com.asdc.multiRedisDatabase.config; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; /**
* @Description: Redis哨兵配置实体类
* @author: Jennifer
* @date: 2018年9月27日 上午10:10:34
*/
@Component
@ConfigurationProperties(prefix = "spring.redis.sentinel")
public class RedisSentinelProperties {
private String master;
private String nodes;
private Integer port; public String getMaster() {
return master;
} public void setMaster(String master) {
this.master = master;
} public String getNodes() {
return nodes;
} public void setNodes(String nodes) {
this.nodes = nodes;
} @Override
public String toString() {
return "RedisProperties [master=" + master + ", nodes=" + nodes + ", port=" + port + "]";
} public void setPort(Integer port) {
this.port = port;
} public Integer getPort() {
return port;
} }
package com.asdc.multiRedisDatabase.config; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper; import redis.clients.jedis.JedisPoolConfig; @Configuration
@EnableAutoConfiguration
public class RedisAloneConfig { @Bean(name = "aloneStringRedisTemplate")
@Primary
public RedisTemplate<String, Object> redisTemplate(@Value("${spring.redis.hostName}") String hostName,
@Value("${spring.redis.port}") int port, @Value("${spring.redis.password}") String password,
@Value("${spring.redis.pool.max-idle}") int maxIdle, @Value("${spring.redis.pool.max-active}") int maxTotal,
@Value("${spring.redis.database}") int index, @Value("${spring.redis.pool.max-wait}") long maxWaitMillis) {
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om); RedisTemplate<String, Object> temple = new RedisTemplate<String, Object>();
temple.setConnectionFactory(
this.connectionFactory(hostName, port, password, maxIdle, maxTotal, index, maxWaitMillis));
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
temple.setKeySerializer(stringSerializer);// key序列化
temple.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
temple.setHashKeySerializer(stringSerializer);// Hash key序列化
temple.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
return temple;
} public RedisConnectionFactory connectionFactory(String hostName, int port, String password, int maxIdle,
int maxTotal, int index, long maxWaitMillis) {
JedisConnectionFactory jedis = new JedisConnectionFactory();
jedis.setHostName(hostName);
jedis.setPort(port);
jedis.setPassword(password);
jedis.setDatabase(index);
jedis.setPoolConfig(this.poolCofig(maxIdle, maxTotal, maxWaitMillis));
// 初始化连接pool
jedis.afterPropertiesSet();
RedisConnectionFactory factory = jedis;
return factory;
} public JedisPoolConfig poolCofig(int maxIdle, int maxTotal, long maxWaitMillis) {
JedisPoolConfig poolCofig = new JedisPoolConfig();
poolCofig.setMaxIdle(maxIdle);
poolCofig.setMaxTotal(maxTotal);
poolCofig.setMaxWaitMillis(maxWaitMillis);
poolCofig.setTestOnBorrow(false);
return poolCofig;
} }
package com.asdc.multiRedisDatabase.config; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper; import redis.clients.jedis.JedisPoolConfig; @Configuration
@EnableAutoConfiguration
public class RedisSentinelConfig { @Autowired
private RedisSentinelProperties properties; @Bean(name = "firstRedisTemplate")
@Primary
public RedisTemplate<Object, Object> redisTemplate() {
return getRedisTemplate(getConnectionFactory());
} @Bean(name = "firstStringRedisTemplate")
@Primary
public StringRedisTemplate stringRedisTemplate() {
return getStringRedisTemplate(getConnectionFactory());
} private RedisTemplate<Object, Object> getRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
template.setConnectionFactory(connectionFactory);
setSerializer(template);
template.afterPropertiesSet();
return template;
} private void setSerializer(RedisTemplate<Object, Object> template) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setKeySerializer(jackson2JsonRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
} private StringRedisTemplate getStringRedisTemplate(RedisConnectionFactory connectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(connectionFactory);
setStringSerializer(template);
template.afterPropertiesSet();
return template;
} private void setStringSerializer(StringRedisTemplate template) {
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
template.setKeySerializer(stringSerializer);
template.setValueSerializer(stringSerializer);
template.setHashKeySerializer(stringSerializer);
template.setHashValueSerializer(stringSerializer);
template.afterPropertiesSet();
} @Bean
public JedisConnectionFactory getConnectionFactory() {
JedisPoolConfig config = new JedisPoolConfig();
JedisConnectionFactory factory = new JedisConnectionFactory(getRedisSentinelConfig(), config);
factory.setPoolConfig(config);
return factory;
} @Bean
public RedisSentinelConfiguration getRedisSentinelConfig() {
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
sentinelConfiguration.setMaster(properties.getMaster());
String sentinelHost = properties.getNodes();
Integer sentinelPort = properties.getPort();
String[] hosts = sentinelHost.split(",");
for (int i = 0; i < hosts.length; i++) {
sentinelConfiguration.sentinel(hosts[i], sentinelPort);
}
return sentinelConfiguration;
} }
package com.asdc.multiRedisDatabase.service; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component; @Component
@SuppressWarnings({ "unchecked", "rawtypes" })
public class RedisService { @Resource(name = "firstStringRedisTemplate")
private StringRedisTemplate stringRedisTemplate; @Resource(name = "firstStringRedisTemplate")
private ValueOperations<String, String> stringRedisOperations; @Resource(name = "firstRedisTemplate")
private RedisTemplate redisTemplate; @Resource(name = "firstRedisTemplate")
private ValueOperations<String, String> redisOperations; @Resource(name = "firstStringRedisTemplate")
private HashOperations<String, String, String> hMapOps; @Resource(name = "firstStringRedisTemplate")
ZSetOperations<String, String> zSetOps; @Resource(name = "firstRedisTemplate")
ListOperations<String, Object> listOps; @Resource(name = "aloneStringRedisTemplate")
private RedisTemplate<String, Object> aloneRedisTemplate; public RedisTemplate<String, Object> getTemplate() {
return aloneRedisTemplate;
} /**
* StringRedisTemplate<br>
* 放入redis,使用默认的过期时间<br>
*
* @param key
* @param value
*/
public void setStringValue(final String key, String value) {
stringRedisOperations.set(key, value);
} /**
* StringRedisTemplate<br>
* 从redis取出value
*
* @param key
* @return
*/
public String getStringValue(final String key) {
return stringRedisOperations.get(key);
} /**
* StringRedisTemplate<br>
* 放入redis,并设置过期时间(分钟)
*
* @param key
* @param value
* @param expireTime
*/
public void setStringValue(final String key, String value, Long expireTime) {
stringRedisOperations.set(key, value);
stringRedisTemplate.expire(key, expireTime, TimeUnit.MINUTES);
} /**
* StringRedisTemplate<br>
* 判断是否存在key
*
* @param key
* @return
*/
public boolean hasKey(final String key) {
return stringRedisTemplate.hasKey(key);
} /**
* StringRedisTemplate<br>
* 删除相应的value
*
* @param key
*/
public void remove(final String key) {
stringRedisTemplate.delete(key);
} public StringRedisTemplate geStringRedisTemplate() {
return this.stringRedisTemplate;
} public RedisTemplate geRedisTemplate() {
return this.redisTemplate;
} /**
* StringRedisTemplate<br>
* 批量删除对应的value
*
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
} /**
* StringRedisTemplate<br>
* 返回 StringRedisOperation
*
* @return
*/
public ValueOperations<String, String> getOperations() {
return this.stringRedisOperations;
} /**
* RedisTemplate<br>
* 获取对象类型的值
*
* @param key
* @return
*/
public Object getObjectValue(String key) {
return redisOperations.get(key);
} /**
* RedisTemplate<br>
* 添加对象类型数据
*
* @param key
* @param object
*/
public void setObjectValue(String key, Object object) {
redisOperations.set(key, (String) object);
} /**
* RedisTemplate<br>
*
* @param key
* @param object
* @param expireTime
*/
/* @SuppressWarnings("unchecked")
public void setObjectValue(String key,Object object ,Long expireTime){
redisOperations.set(key, object);
redisTemplate.expire(key, expireTime, TimeUnit.MINUTES);
}*/ public void increment(String key, Long delta) {
redisOperations.increment(key, delta);
} public void expire(String key, Long expireTime) {
redisTemplate.expire(key, expireTime, TimeUnit.MINUTES);
} public void expire(String key, Long expireTime, TimeUnit unit) {
stringRedisTemplate.expire(key, expireTime, unit);
} public Set getKeysByPattern(String pattern) {
return redisTemplate.keys(pattern);
} public void setHash(String key, String hashKey, String value) {
hMapOps.put(key, hashKey, value);
} public String getHashValue(String key, String mapKey) {
return hMapOps.get(key, mapKey);
} public Map<String, String> getHashAll(String key) {
return hMapOps.entries(key);
} public long setHashIncrement(String key, String hashKey, long counts) {
return hMapOps.increment(key, hashKey, counts);
} public long size(String key) {
return hMapOps.size(key);
} public long lookTimeOut(String key, TimeUnit timeUnit) {
return stringRedisTemplate.getExpire(key, timeUnit);
} public boolean zAddZsetElement(String key, String value, long score) {
return zSetOps.add(key, value, score);
} public Double getZsetScore(String key, String value) {
return zSetOps.score(key, value);
} public long getListSize(String key) {
return listOps.size(key);
} public List<Object> getList(String key) {
return listOps.range(key, 0L, -1L);
} public void addList(String key, List<Object> values) {
if (values == null || values.size() == 0) {
return;
} listOps.rightPushAll(key, values);
} /**
* 获取自增值
*
* @param key
* @return
*/
public int getIncrValue(final String key) { return stringRedisTemplate.execute(new RedisCallback<Integer>() {
@Override
public Integer doInRedis(RedisConnection connection) throws DataAccessException {
RedisSerializer<String> serializer = stringRedisTemplate.getStringSerializer();
byte[] rowkey = serializer.serialize(key);
byte[] rowval = connection.get(rowkey);
try {
String val = serializer.deserialize(rowval);
return Integer.parseInt(val);
} catch (Exception e) {
return 0;
}
}
});
} @PostConstruct
public void init() {
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
} public long delOfflineContent(String contentId, String listId) {
return listOps.remove(listId, 1, contentId);
}
}
package com.asdc.multiRedisDatabase; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class MultiRedisDatabaseApplication { public static void main(String[] args) {
SpringApplication.run(MultiRedisDatabaseApplication.class, args);
}
}
package com.asdc.multiRedisDatabase.controller; import java.util.Date;
import java.util.Iterator;
import java.util.Set; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import com.asdc.multiRedisDatabase.service.RedisService; /**
* @Description: 数据同步控制器
* @author: Jennifer
* @date: 2018年9月27日 上午11:25:24
*/
@RestController
public class SyncController {
@Autowired
private RedisService redisService; private static Long EXPIRE_TIME = 61 * 24 * 60L; @RequestMapping("/sync")
@ResponseBody
public String sync() {
RedisTemplate<String, Object> template = redisService.getTemplate();
Set<String> keys = template.keys("*");
int count = 0;
for (Iterator<?> iterator = keys.iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
try {
Integer value = (Integer) template.opsForValue().get(key);
if (value != null) {
redisService.setStringValue(key, value.toString(), EXPIRE_TIME);
count++;
}
} catch (Exception e) {
}
}
return String.format("单机Redis总记录数: %s ,Sentinel有效导入数: %s ,记录时间: %s", String.valueOf(keys.size()), count,
new Date());
}
}
package com.asdc.multiRedisDatabase; import java.util.Date;
import java.util.Iterator;
import java.util.Set; import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner; import com.asdc.multiRedisDatabase.config.RedisSentinelConfig;
import com.asdc.multiRedisDatabase.service.RedisService; @RunWith(SpringRunner.class)
@SpringBootTest
public class MultiRedisDatabaseApplicationTests {
@Autowired
private RedisService redisService; private static Long EXPIRE_TIME = 61 * 24 * 60L; private static Logger logger = LoggerFactory.getLogger(RedisSentinelConfig.class); @Test
public void getKeys() {
RedisTemplate<String, Object> template = redisService.getTemplate();
Set<String> keys = template.keys("*");
int count = 0;
for (Iterator<?> iterator = keys.iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
try {
Integer value = (Integer) template.opsForValue().get(key);
if (value != null) {
logger.info(count++ + ":" + key + " = " + value);
redisService.setStringValue(key, value.toString(), EXPIRE_TIME);
}
} catch (Exception e) {
}
}
logger.info(String.format("总记录数: %s ,有效导入数: %s ,记录时间: %s", String.valueOf(keys.size()), count, new Date()));
} }
Redis单机数据迁移至Sentinel集群的更多相关文章
- 数据迁移_老集群RAC迁移数据恢复到新集群RAC
数据迁移_老集群RAC迁移数据恢复到新集群RAC 作者:Eric 微信:loveoracle11g 1.把老集群RAC备份的数据远程拷贝到新集群RAC [root@old-rac-node1 ~]# ...
- CentO7 安装 redis, 主从配置,Sentinel集群故障转移切换
一.Redis的安装(前提是已经安装了EPEL) 安装redis: yum -y install redis 启动/停止/重启 Redis 启动服务: systemctl start re ...
- hadoop hdfs 数据迁移到其他集群
# hadoop fs -cat /srclist Warning: $HADOOP_HOME is deprecated. hdfs://sht-sgmhadoopcm-01:9011/jdk-6u ...
- helm安装redis+Sentinel集群搭建
一.redis集群特点 数据 在多个Redis节点之间自动分片 sentinel特点: 它的主要功能有以下几点 不时地监控redis是否按照预期良好地运行; 如果发现某个redis节点运行出现状况,能 ...
- Redis Sentinel集群双机房容灾实施步骤
概要目标防止双机房情况下任一个机房完全无法提供服务时如何让Redis继续提供服务.架构设计A.B两机房,其中A机房有一Master一Slave和两个Sentinel,B机房只有2个Sentinel,如 ...
- redis sentinel集群的搭建
背景说明: 这里采用1主2从的redis集群,3个sentinel搭建高可用redis集群. 一,关于搭建redis-sentinel高可用之前,我们必须要了解redis主从搭建redis-senti ...
- Redis Sentinel 集群安装 step by step
一. 准备材料 服务器 IP address 操作系统 位数 Redis 版本 CNT06CAH05 192.168.3.47 CentOS 6.5 x64 Redis-3.2.6 sentine ...
- 从零自学Hadoop(17):Hive数据导入导出,集群数据迁移下
阅读目录 序 将查询的结果写入文件系统 集群数据迁移一 集群数据迁移二 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephis ...
- redis sentinel 集群监控 配置
环境: ip 172.16.1.31 26379 redis sentinel ip 172.16.1.30 6379 主 1 ip 172.16.1.31 6380 从 1 ip ...
随机推荐
- 在CMD中建立一个不能删除的文件
Windows 下不能够以下面这些字样来命名文件/文件夹,包括:“aux”“com1”“com2”“prn”“con”和“nul”等,因为这些名字都属于设备名称,等价于一个 DOS 设备,如果我们把文 ...
- “全栈2019”Java第二十一章:流程控制语句中的决策语句if
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- SP2666 QTREE4 - Query on a tree IV(LCT)
题意翻译 你被给定一棵n个点的带边权的树(边权可以为负),点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的权值之和. 一开始所有的点都是白色的. 要求作以下 ...
- [ActionScript 3.0] 使TextField呈现手型的简单方法
有的人不知道这个方法,有时候为了给文本添加手型做了很多复杂的工作,虽然是可以实现,但心里有没有一种难以接受的感觉?那我们看看这个吧, 例子一看就懂: var str:String="显示手形 ...
- redis 3.0 集群__安装
参考文档 http://redis.io/topics/cluster-tutorial http://redis.io/topics/cluster-spec http://redis.readth ...
- ZooKeeper参数
原文连接:https://www.cnblogs.com/skyl/p/4854553.html ZooKeeper参数调优 zookeeper的默认配置文件为zookeeper/conf/zoo ...
- windows本地搭建nginx+php+mysql+redis环境详细步骤
1.mysql的下载和安装 这个可参考我另外一篇文章:http://www.cnblogs.com/myIvan/p/9265645.html 2.php的下载和配置修改 下载地址:https://w ...
- fetch网络请求 get 和 post
//在React Native中,使用fetch实现网络请求 /* fetch 是一个封装程度更高的网络API, 使用了Promise* Promise 是异步编程的一种解决方案* Promise 对 ...
- USART列子
#include "stm32f10x.h" void USART_INit(void) { GPIO_InitTypeDef GPIO_Initstructe; USART_In ...
- 进阶篇:2.1)DFMA实施障碍和关键
本章目的:了解DFMA实施障碍与关键. 1.实施的障碍 面向制造和装配的产品开发能够降低产品成本.提高产品质量.缩短产品开发周期,但是,由于传统产品开发思想和各种条件的限制,实施面向制造和装配的产品开 ...