首页 文章 精选 留言 我的

精选列表

搜索[整合],共10003篇文章
优秀的个人博客,低调大师

spring-boot整合protobuf

简介:protobuf是Google的语言中立,平台中立,可扩展的机制,用于序列化结构化数据 - 想想XML,但更小,更快,更简单。您可以定义数据的结构化结构,然后使用特殊生成的源代码轻松地将结构化数据写入和读取各种数据流,并使用各种语言。1.在项目中导入依赖 <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.8.0</version> </dependency> 2.创建ReturnVO. proto文件 syntax = "proto3";

优秀的个人博客,低调大师

spring 整合spring data jpa

一、导入依赖 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> </dependency> 二、配置jpa <?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xmlns:cache="http://www.springframework.org/schema/cache"xmlns:jaxws="http://cxf.apache.org/jaxws"xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd" default-lazy-init="true"> <context:property-placeholderlocation="classpath:/config/config.properties"/> <!--数据源--> <beanid="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource"> <propertyname="user"value="${jdbc.user}"/> <propertyname="password"value="${jdbc.password}"/> <propertyname="driverClass"value="${jdbc.driverClass}"/> <propertyname="jdbcUrl"value="${jdbc.jdbcUrl}"/> </bean> <!--JpaEntityManager配置--> <beanid="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <propertyname="dataSource"ref="dataSource"/> <!--指定Jpa持久化实现厂商类,这里以Hibernate为例--> <propertyname="jpaVendorAdapter"ref="jpaVendorAdapter"></property> <!--指定Entity实体类包路径--> <propertyname="packagesToScan"value="com.web"/> <!--指定JPA属性;如Hibernate中指定是否显示SQL的是否显示、方言等--> <propertyname="jpaProperties"> <props> <!--命名规则My_NAME->MyName--> <propkey="hibernate.ejb.naming_strategy">org.hibernate.cfg.DefaultComponentSafeNamingStrategy</prop> <!--打印sql语句--> <propkey="hibernate.show_sql">true</prop> <!--格式化sql语句--> <propkey="hibernate.format_sql">true</prop> </props> </property> </bean> <beanid="jpaVendorAdapter"class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <!--自动检查注解的实体和数据表,如果数据库不存在的标,会根据实体自动生成--> <propertyname="generateDdl"value="false"/> <propertyname="database"value="HSQL"/> </bean> <beanid="jpaDialect"class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> <!--配置事务--> <beanid="transactionManager"class="org.springframework.orm.jpa.JpaTransactionManager"> <propertyname="entityManagerFactory"ref="entityManagerFactory"></property> </bean> <!--配置支持基于注解的事务--> <tx:annotation-driventransaction-manager="transactionManager"/> <!--重要配置:启用扫描并自动创建代理的功能--> <jpa:repositoriesbase-package="com.web"transaction-manager-ref="transactionManager"entity-manager-factory-ref="entityManagerFactory"/> </beans> 三、实现接口 (因为CrudRepository集成的是顶层接口Repository实现了简单的crud操作) publicinterfaceUserInfoRepositoryextendsCrudRepository<UserInfo,Long>{ } 四、注入使用 @Service publicclassUserInfoServiceImplimplementsUserInfoService{ @Autowired privateUserInfoRepositoryrepository; @Override publicList<UserInfo>findAll(){ return(List<UserInfo>)repository.findAll(); } }

优秀的个人博客,低调大师

Elasticsearch 与 Kafka 整合剖析

1.概述 目前,随着大数据的浪潮,Kafka 被越来越多的企业所认可,如今的Kafka已发展到0.10.x,其优秀的特性也带给我们解决实际业务的方案。对于数据分流来说,既可以分流到离线存储平台(HDFS),离线计算平台(Hive仓库),也可以分流实时流水计算(Storm,Spark)等,同样也可以分流到海量数据查询(HBase),或是及时查询(ElasticSearch)。而今天笔者给大家分享的就是Kafka 分流数据到ElasticSearch。 2.内容 我们知道,ElasticSearch是有其自己的套件的,简称ELK,即ElasticSearch,Logstash以及Kibana。ElasticSearch负责存储,Logstash负责收集数据来源,Kibana负责可视化数据,分工明确。想要分流Kafka中的消息数据,可以使用Logstash的插件直接消费,但是需要我们编写复杂的过滤条件,和特殊的映射处理,比如系统保留的`_uid`字段等需要我们额外的转化。今天我们使用另外一种方式来处理数据,使用Kafka的消费API和ES的存储API来处理分流数据。通过编写Kafka消费者,消费对应的业务数据,将消费的数据通过ES存储API,通过创建对应的索引的,存储到ES中。其流程如下图所示: 上图可知,消费收集的数据,通过ES提供的存储接口进行存储。存储的数据,这里我们可以规划,做定时调度。最后,我们可以通过Kibana来可视化ES中的数据,对外提供业务调用接口,进行数据共享。 3.实现 下面,我们开始进行实现细节处理,这里给大家提供实现的核心代码部分,实现代码如下所示: 3.1 定义ES格式 我们以插件的形式进行消费,从Kafka到ES的数据流向,只需要定义插件格式,如下所示: { "job": { "content": { "reader": { "name": "kafka", "parameter": { "topic": "kafka_es_client_error", "groupid": "es2", "bootstrapServers": "k1:9094,k2:9094,k3:9094" }, "threads": 6 }, "writer": { "name": "es", "parameter": { "host": [ "es1:9300,es2:9300,es3:9300" ], "index": "client_error_%s", "type": "client_error" } } } } } 这里处理消费存储的方式,将读和写的源分开,配置各自属性即可。 3.2 数据存储 这里,我们通过每天建立索引进行存储,便于业务查询,实现细节如下所示: public class EsProducer { private final static Logger LOG = LoggerFactory.getLogger(EsProducer.class); private final KafkaConsumer<String, String> consumer; private ExecutorService executorService; private Configuration conf = null; private static int counter = 0; public EsProducer() { String root = System.getProperty("user.dir") + "/conf/"; String path = SystemConfigUtils.getProperty("kafka.x.plugins.exec.path"); conf = Configuration.from(new File(root + path)); Properties props = new Properties(); props.put("bootstrap.servers", conf.getString("job.content.reader.parameter.bootstrapServers")); props.put("group.id", conf.getString("job.content.reader.parameter.groupid")); props.put("enable.auto.commit", "true"); props.put("auto.commit.interval.ms", "1000"); props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); consumer = new KafkaConsumer<String, String>(props); consumer.subscribe(Arrays.asList(conf.getString("job.content.reader.parameter.topic"))); } public void execute() { executorService = Executors.newFixedThreadPool(conf.getInt("job.content.reader.threads")); while (true) { ConsumerRecords<String, String> records = consumer.poll(100); if (null != records) { executorService.submit(new KafkaConsumerThread(records, consumer)); } } } public void shutdown() { try { if (consumer != null) { consumer.close(); } if (executorService != null) { executorService.shutdown(); } if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) { LOG.error("Shutdown kafka consumer thread timeout."); } } catch (InterruptedException ignored) { Thread.currentThread().interrupt(); } } class KafkaConsumerThread implements Runnable { private ConsumerRecords<String, String> records; public KafkaConsumerThread(ConsumerRecords<String, String> records, KafkaConsumer<String, String> consumer) { this.records = records; } @Override public void run() { String index = conf.getString("job.content.writer.parameter.index"); String type = conf.getString("job.content.writer.parameter.type"); for (TopicPartition partition : records.partitions()) { List<ConsumerRecord<String, String>> partitionRecords = records.records(partition); for (ConsumerRecord<String, String> record : partitionRecords) { JSONObject json = JSON.parseObject(record.value()); List<Map<String, Object>> list = new ArrayList<>(); Map<String, Object> map = new HashMap<>(); index = String.format(index, CalendarUtils.timeSpan2EsDay(json.getLongValue("_tm") * 1000L)); if (counter < 10) { LOG.info("Index : " + index); counter++; } for (String key : json.keySet()) { if ("_uid".equals(key)) { map.put("uid", json.get(key)); } else { map.put(key, json.get(key)); } list.add(map); } EsUtils.write2Es(index, type, list); } } } } } 这里消费的数据源就处理好了,接下来,开始ES的存储,实现代码如下所示: public class EsUtils { private static TransportClient client = null; static { if (client == null) { client = new PreBuiltTransportClient(Settings.EMPTY); } String root = System.getProperty("user.dir") + "/conf/"; String path = SystemConfigUtils.getProperty("kafka.x.plugins.exec.path"); Configuration conf = Configuration.from(new File(root + path)); List<Object> hosts = conf.getList("job.content.writer.parameter.host"); for (Object object : hosts) { try { client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(object.toString().split(":")[0]), Integer.parseInt(object.toString().split(":")[1]))); } catch (Exception e) { e.printStackTrace(); } } } public static void write2Es(String index, String type, List<Map<String, Object>> dataSets) { BulkRequestBuilder bulkRequest = client.prepareBulk(); for (Map<String, Object> dataSet : dataSets) { bulkRequest.add(client.prepareIndex(index, type).setSource(dataSet)); } bulkRequest.execute().actionGet(); // if (client != null) { // client.close(); // } } public static void close() { if (client != null) { client.close(); } } } 这里,我们利用BulkRequestBuilder进行批量写入,减少频繁写入率。 4.调度 存储在ES中的数据,如果不需要长期存储,比如:我们只需要存储及时查询数据一个月,对于一个月以前的数据需要清除掉。这里,我们可以编写脚本直接使用Crontab来进行简单调用即可,脚本如下所示: #!/bin/sh # <Usage>: ./delete_es_by_day.sh kafka_error_client logsdate 30 </Usage>echo "<Usage>: ./delete_es_by_day.sh kafka_error_client logsdate 30 </Usage>" index_name=$1 daycolumn=$2 savedays=$3 format_day=$4 if [ ! -n "$savedays" ]; then echo "Oops. The args is not right,please input again...." exit 1 fi if [ ! -n "$format_day" ]; then format_day='%Y%m%d' fi sevendayago=`date -d "-${savedays} day " +${format_day}` curl -XDELETE "es1:9200/${index_name}/_query?pretty" -d " { "query": { "filtered": { "filter": { "bool": { "must": { "range": { "${daycolumn}": { "from": null, "to": ${sevendayago}, "include_lower": true, "include_upper": true } } } } } } } }" echo "Finished." 然后,在Crontab中进行定时调度即可。 5.总结 这里,我们在进行数据写入ES的时候,需要注意,有些字段是ES保留字段,比如`_uid`,这里我们需要转化,不然写到ES的时候,会引发冲突导致异常,最终写入失败。 6.结束语 这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉 联系方式: 邮箱:smartloli.org@gmail.com Twitter: https://twitter.com/smartloli QQ群(Hadoop - 交流社区1): 424769183 温馨提示:请大家加群的时候写上加群理由(姓名+公司/学校),方便管理员审核,谢谢! 热爱生活,享受编程,与君共勉! 作者:哥不是小萝莉 [关于我][犒赏] 出处:http://www.cnblogs.com/smartloli/ 转载请注明出处,谢谢合作!

优秀的个人博客,低调大师

RBAC模型整合数据权限

在项目实际开发中我们不光要控制一个用户能访问哪些资源,还需要控制用户只能访问资源中的某部分数据。 控制一个用户能访问哪些资源我们有很成熟的权限管理模型即RBAC,但是控制用户只能访问某部分资源(即我们常说的数据权限)使用RBAC模型是不够的,本文我们尝试在RBAC模型的基础上融入数据权限的管理控制。 首先让我们先看下RBAC模型。 RBAC模型 RBAC是Role-BasedAccess Control的英文缩写,意思是基于角色的访问控制。 RBAC事先会在系统中定义出不同的角色,不同的角色拥有不同的权限,一个角色实际上就是一组权限的集合。而系统的所有用户都会被分配到不同的角色中,一个用户可能拥有多个角色。使用RBAC可以极大地简化权限的管理。 RBAC模型还可以细分为RBAC0,RBAC1,RBAC2,RBAC3。这里我们不讨论他们之间的差异,感兴趣的同学可以自行研究,我们主要聚焦于常见的RBAC0模型上。 如下图就是一个经典RBAC0模型的数据库设计。 RBAC0 在RBAC模型下,系统只会验证用户A是否属于角色RoleX,而不会判断用户A是否能访问只属于用户B的数据DataB。这种问题我们称之为“水平权限管理问题”。 数据权限 列表数据权限,主要通过数据权限控制行数据,让不同的人有不同的查看数据规则;要实现数据权限,最重要的是需要抽象出数据规则。 数据规则 比如我们系统的商机数据,需要从下面几个维度来控制数据访问权限。 销售人员只能看自己的数据; 各大区的销售经理只能看各区域的数据(安徽大区的销售经理看安徽区域的商机数据),同理也适用于某BG分管领导只能看所在BG的商机数据; 财务人员只能看金额小于一万的数据。 上面的这些维度就是数据规则。 这样数据规则的几个重点要素我们也明晰了,就是规则字段,规则表达式,规则值,上面三个场景对应的规则分别如下: 规则字段:创建人,规则表达式:= ,规则值:当前登录人 规则字段:所属大区,规则表达式:= ,规则值:安徽大区 规则字段:销售金额,规则表达式:< ,规则值:10000 数据规则 规则字段配置说明:条件表达式:大于/大于等于/小于/小于等于/等于/包含/模糊/不等于规则值:指定值(固定值/系统上下文变量) 关联资源、用户 光有数据规则是不够的,我们还需要把数据规则跟资源和用户进行绑定。 数据规则与资源的绑定很简单,我们只需要建立一个中间表即可,如下图所示: 这样资源就可以关联上了数据规则。 在应用设计上我们需要一个单独的数据规则管理功能,方便我们录入数据规则,然后在资源管理页面(比如商机列表)上就可以选择内置的数据规则进行资源与规则的绑定。 「那么如何让不同的用户拥有不同的数据规则呢?」 在RBAC模型中,用户是通过授予不同的角色来进行资源的管理,同理我们可以让角色在授予权限的时候关联上数据规则,这样最终在系统上就体现为不同的用户拥有不同的数据规则。 有点拗口,我们还是按上面的例子来说。 销售人员、大区销售经理、财务人员属于不同的角色,他们都拥有商机列表这个资源权限,但是在给这些角色绑定商机列表资源权限时我们可以勾选对应的数据规则(上面已经实现资源与数据规则的绑定)。体现在数据库设计中我们可以在角色资源对应关系表 Role_Permission中添加一个字段用于存储关联的数据规则,如果有多个数据规则可以使用分隔符分割。 最终RBAC模型演变成如下所示的模型: 按照上面的设计我们需要区分各个大区管理的数据权限则需要建立不同的大区角色,如安徽大区销售经理、上海大区销售经理,然后分别给角色勾选对应的数据规则。这里就类似于RBAC1中的角色继承的概念了。 这样我们就基本实现了RBAC与数据规则的绑定,但是我们还有个问题就是如何在系统中落地。 这里我们就要借助大名鼎鼎的AOP来实现了,这篇文章只讲原理不讲实现,所以我们只顺带提一下实现方案。 自定义一个数据权限的注解,比如叫 PermissionData 在对应的资源请求方法,比如商机列表上添加自定义注解 @PermissionData 利用AOP抓取到用户对应角色的所有数据规则并进行SQL拼接,最终在SQL层面实现数据过滤。 继续优化 在上面的设计中我们通过给不同角色绑定不同数据规则实现了数据权限,但是考虑下面一种场景:某角色需要看到的数据范围为 “所属大区为安徽大区且事业部为消费者事业部的商机数据”,在这种场景里按照我们之前的设计需要建立两个数据规则: 所属大区 = 安徽大区 所属事业部 = 消费者事业部 然后再建立2个不同的角色,分别授予不同的数据规则,如果这样的场景比较多的话很容易出现角色爆炸的情况,所有我们这里再抽取出 数据规则组的概念。 一个数据规则组有多个数据规则,数据规则之间通过 AND进行连接,放一张应用设计图: 体现在数据库设计中就变成了如下所示: 小结 通过上面8张表的设计我们实现了RBAC模型与数据权限的结合,当然这里还有继续优化的空间。比如这里的规则字段和规则值我们可以抽取出对应的字典表,让数据规则表去关联这些字典字段,这样在应用层配置数据规则的时候就不需要管理员手动填写而是从字典项中去选择了,减少了数据规则配置出错的概率。 数据权限是一个实现相对比较复杂的功能,这里我们选择的是在RBAC模型基础上进行扩展,如果你有更好的解决方案欢迎留言告诉我。 End 干货分享 这里为大家准备了一份小小的礼物,关注公众号,输入如下代码,即可获得百度网盘地址,无套路领取!001:《程序员必读书籍》002:《从无到有搭建中小型互联网公司后台服务架构与运维架构》003:《互联网企业高并发解决方案》004:《互联网架构教学视频》006:《SpringBoot实现点餐系统》007:《SpringSecurity实战视频》008:《Hadoop实战教学视频》009:《腾讯2019Techo开发者大会PPT》 010:微信交流群 近期热文top 1、关于JWT Token 自动续期的解决方案 2、SpringBoot开发秘籍-事件异步处理 3、架构师之路-服务器硬件扫盲 4、基于Prometheus和Grafana的监控平台 - 环境搭建 5、RocketMQ进阶-事务消息 我就知道你“在看” 本文分享自微信公众号 - JAVA日知录(javadaily)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

使用IOTA整合物联网硬件

本教程面向iota初学者,我们将学习如何开发基于指定IOTA地址的余额来闭合或断开一个连接到树莓派上的继电器,点亮或熄灭LED。教程虽然简单,但足以展示IOTA的强大能力。 我们将使用一个联网的树莓派作为物联网设备,使用Python来检查IOTA tangle上的余额,并使用树莓派的内部GIO管脚来切换所连接的继电器的闭合与断开。然后我们会将继电器连接到一个电池供电的简单LED电路,用来表示我们项目中的物理设备。 要快速掌握区块链和数字货币应用开发,推荐汇智网的区块链开发系列在线教程。 内容涵盖比特币、以太坊、EOS、超级账本、Tendermint等多种主流区块链 平台,同时支持Java、C#、Python、PHP、JavaScript、Dart等多种开发 语言。 元器件 先让我们看一下项目需要的元器件。你应当可以在大多数电子元器件商店或者淘宝上卖到这些元器件,不会超过350元。 树莓派 项目的大脑是树莓派。树莓派将运行用来监视IOTA地址的余额并处理树莓派的通用输入输出(GIO)管脚上的信号: 继电器 继电器用来切换电路以及设备(我们这里就是LED)的开关。为了简化电路我们将使用一个继电器模块,它包含了所有必须的元器件、管脚和接插件。注意你也可以购买多通道继电器模块,只要每个通道可以单独开关即可。 面包板 面包板用来进行电路的连接而无需进行焊接,这使得装配过程更加简单。 发光二极管 当供电时LED会点亮,我们用它来表示项目中的物理设备(比如冰箱)。 300欧电阻 电阻用来限制通过LED的电流。没有电阻的话,LED和树莓派可能会因为电流过大而损坏。要使用的电阻取决于你的LED以及电路电压。在我的演示中,使用了9V电池,因此330欧姆的电阻应当就可以了。 电池 电池为电路提供能力。我的演示中使用的是9v电池。 连接线 我们当然也需要一些电线将各个部件连接起来: 二维码 如果你希望使用手机IOTA钱包来支付使用LED(冰箱、洗衣机....)的费用,那么一个打印好的IOTA收款地址二维码会很方便。当使用IOTA钱包生成地址时,你会找到一个二维码。或者在THETANGLE网站查询已有地址的二维码。 组装电路 现在我们看下组装好的电路: 树莓派的管脚如下: 参考以下说明连接管脚: 树莓派的pin 2(5v)连接到继电器模块的VCC管脚 树莓派的pin 6(地)连接到继电器模块的GND管脚 树莓派的pin 12(GPIO18)连接到继电器模块的IN管脚 继电器模块的COM端子连接到电池的正极 继电器模块的NO端子通过电阻连接到LED的正极 电池的负极连接到LED的负极 需要的软件和库 在我们开始编写Python代码之前,需要先确认已经在树莓派上安装了所需要的软件和库。 首先,我们需要在树莓派上安装一个操作系统。任何树莓派支持的LInux发行版应该都可以。在我的演示中,使用的是Raspbian发行版,因为它已经预置了Python和几个Python编辑器。Raspbian发行版的安装指令可以在这里找到: https://www.raspberrypi.org/downloads/raspbian/。 如果你要单独安装Python,可以参考这里: https://www.python.org/downloads/。 最后,我们需要安装PyIOTA API库,利用它我们就可以使用Python来访问IOTA tangle了。PyIOTA API库及安装指令参见: ttps://github.com/iotaledger/iota.lib.py。 Python代码 现在开始写代码: # Imports some Python Date/Time functions import time import datetime # Imports GPIO library import RPi.GPIO as GPIO # Imports the PyOTA library from iota import Iota from iota import Address # Setup O/I PIN's LEDPIN=18 GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(LEDPIN,GPIO.OUT) GPIO.output(LEDPIN,GPIO.LOW) # Function for checking address balance on the IOTA tangle. def checkbalance(): print("Checking balance") gb_result = api.get_balances(address) balance = gb_result['balances'] return (balance[0]) # URL to IOTA fullnode used when checking balance iotaNode = "https://nodes.thetangle.org:443" # Create an IOTA object api = Iota(iotaNode, "") # IOTA address to be checked for new light funds # IOTA addresses can be created using the IOTA Wallet address = [Address(b'GTZUHQSPRAQCTSQBZEEMLZPQUPAA9LPLGWCKFNEVKBINXEXZRACVKKKCYPWPKH9AWLGJHPLOZZOYTALAWOVSIJIYVZ')] # Get current address balance at startup and use as baseline for measuring new funds being added. currentbalance = checkbalance() lastbalance = currentbalance # Define some variables lightbalance = 0 balcheckcount = 0 lightstatus = False # Main loop that executes every 1 second while True: # Check for new funds and add to lightbalance when found. if balcheckcount == 10: currentbalance = checkbalance() if currentbalance > lastbalance: lightbalance = lightbalance + (currentbalance - lastbalance) lastbalance = currentbalance balcheckcount = 0 # Manage light balance and light ON/OFF if lightbalance > 0: if lightstatus == False: print("light ON") GPIO.output(LEDPIN,GPIO.HIGH) lightstatus=True lightbalance = lightbalance -1 else: if lightstatus == True: print("light OFF") GPIO.output(LEDPIN,GPIO.LOW) lightstatus=False # Print remaining light balance print(datetime.timedelta(seconds=lightbalance)) # Increase balance check counter balcheckcount = balcheckcount +1 # Pause for 1 sec. time.sleep(1) 运行代码 要运行上面的代码,我们需要先在树莓派上保存到文件中,例如let_there_be_light.py。然后使用如下命令: python let_there_be_light.py 现在你应当可以在终端窗口中看到代码在执行了,显示当前的余额,并且每隔10秒钟检查一次LED对应的IOTA地址的余额。 支付LED的使用费 要点亮LED,你只需要使用喜欢的IOTA钱包向LED的IOTA地址转一些IOTA币。只要转账交易被IOTA tangle确认,LED应该就会点亮并直到消耗完余额。在我的演示当中,我设置的收费标准是1秒钟1个IOTA。 原文链接:iota物联网硬件集成新手教程 - 汇智网

优秀的个人博客,低调大师

spring-cloud-stream整合kafka

1.在项目的pom中引入 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-kafka</artifactId> </dependency> 2.配置消息通道 public interface Demo { /** * 发消息的通道名称 */ String DEMO_OUTPUT = "demo_output"; /** * 消息的订阅通道名称 */ String DEMO_INPUT = "demo_input"; /** * 发消息的通道 * * @return */ @Output(DEMO_OUTPUT) MessageChannel sendDemoMessage(); /** * 收消息的通道 * * @return */ @Input(DEMO_INPUT) SubscribableChannel recieveDemoMessage(); } 使带注释组件的结合Input和Output根据作为值给注释传递接口的列表到代理 @EnableBinding(value = {Demo.class}) 4.链接kafka配置 spring.cloud.stream.bindings.demo_input.destination=demo spring.cloud.stream.bindings.demo_input.group=demo spring.cloud.stream.bindings.demo_output.destination=demo spring.cloud.stream.bindings.demo_output.group=demo spring.cloud.stream.default-binder=kafka spring.kafka.bootstrap-servers=127.0.0.1:9092 spring.kafka.consumer.enable-auto-commit=true spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.ByteArraySerializer spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.ByteArraySerializer 5.发送消息 @Resource(name = Demo.DEMO_OUTPUT) private MessageChannel sendDemoMessageChannel; @Test public void Demo() { boolean isSendSuccess = sendDemoMessageChannel. send(MessageBuilder.withPayload("OK").build()); System.out.println(isSendSuccess); } 6.接收消息 @StreamListener(Demo. DEMO_INPUT) public void insertQuotationK(Message<String> message) { if (StringUtils.isEmpty(message.getPayload())) { System.out.println("receiver data is empty !"); System.out.println(400 + "failed"); } System.out.println("kafka收到"+message.getPayload()); } 7.结束咯,如果出现异常,请留言。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Apache Tomcat

Apache Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

JDK

JDK

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。