首页 文章 精选 留言 我的

精选列表

搜索[教程],共10001篇文章
优秀的个人博客,低调大师

多平台Docker镜像构建教程

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! Adrian Mouat被誉为Docker Captain,他是Container Solutions 公司的首席科学家。目前,他正开发 Trow,这是一个容器镜像注册中心,用于安全管理 Kubernetes 集群中的镜像流。 当前,Docker 镜像已经成为测试和部署新的第三方软件的标准工具。Adrian 是开源 Trow 注册中心的主要开发者,而Docker 镜像则是人们安装该工具的主要方式。如果他不提供镜像,其他人最终也会推出他们自己的镜像,这样会导致重复"造轮子”,并产生维护问题。 默认情况下,我们创建的Docker 镜像运行在 linux/amd64 平台上。它适用于大多数的开发机器和云提供商,但却忽略其他平台的用户。这个群体很庞大——想想基于树莓派的家庭实验室、生产物联网设备的公司、运行在 IBM 大型机上的组织以及使用低功耗 arm64 芯片的云。 一般来说,这些平台的用户通常会构建自己的镜像或寻找其他解决方案。 那么,你该如何为这些平台构建镜像?最明显的方法是在目标平台上构建镜像。这适用于很多情况。但是如果你的目标是 s390x,我希望你有可以使用的 IBM 大型机。更常见的平台,比如树莓派、物联网设备通常电量有限,速度慢或无法构建镜像。 我们该怎么做?有两个选项:1. 目标平台仿真,2. 交叉编译。有趣的是,我发现有种方法可以将这两个选项结合的效果最好。 1.仿真 让我们从第一个选项——仿真开始。有一个很不错的项目叫 QEMU,它可以模拟很多平台。随着最近 buildx 的预览,将 QEMU 用于 Docker 变得更加容易。 https://www.qemu.org/ https://github.com/docker/buildx QEMU 集成依赖于一个 Linux 内核特性,该特性有个稍显神秘的名字 binfmt_misc handler。当 Linux 遇到其无法识别的可执行文件格式(例如,一个用于不同体系结构的文件格式)时,它将使用该处理程序检查是否配置了什么“用户空间应用程序”来处理该格式(例如,模拟器或 VM)。如果有,它将把可执行文件传递给该应用程序。 为实现这一点,我们需要在内核中注册我们关注的平台。如果你正在使用 Docker Desktop,那么对于大多数常见平台,你就无需做这项工作。如果你正使用 Linux,你可以通过运行最新的docker/binfmt镜像,以与 Docker Desktop 相同的方式注册处理程序,例如: docker run --privileged --rm docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64 完成此操作后,你可能需要重启 Docker。如果你想要对自己想注册的平台有更多控制或想使用更高深莫测的平台(例如 PowerPC),请查看 qus 项目。 https://github.com/dbhi/qus Buildx 有两种不同的用法,但最简单的方法可能是在 Docker CLI 上启用实验性特性(如果你还没有这样做的话),编辑~/.docker/config.json文件,使其包含以下内容: { ... "experimental": “enabled” } 你现在应该能运行docker buildx ls,并得到类似以下的输出: $ docker buildx ls NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS default docker default default running linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 让我们为另一个平台构建一个镜像,从 Dockerfile 开始: FROM debian:buster CMD uname -m 如果我们正常构建,运行以下命令: $ docker buildx build -t local-build . … $ docker run --rm local-build x86_64 但是,如果我们显式指定构建针对的平台,则执行以下命令: $ docker buildx build --platform linux/arm/v7 -t arm-build . … $ docker run --rm arm-build armv7l 成功!我们已经成功地在 x86_64 笔记本上构建和运行了 armv7 镜像,并且只做了很少工作。这种技术很有效,但对于更复杂的构建,你可能会发现它运行太慢,或者遇到 QEMU 中的 Bug。在这些情况下,有必要研究一下是否可以交叉编译你的镜像。 2.交叉编译 一些编译器能为 foreign platforms 生成二进制代码,最著名的包括 Go 和 Rust。通过 Trow 注册中心项目,我们发现,交叉编译是为其他平台创建镜像最快、最可靠的方法。例如,这里是 Trow armv7 镜像的 Dockerfile。 https://github.com/ContainerSolutions/trow/blob/master/docker/Dockerfile.armv7 最重要的一行是: RUN cargo build --target armv7-unknown-linux-gnueabihf -Z unstable-options --out-dir ./out 它明确告诉 Rust,我们希望二进制文件在哪个平台上运行。然后,我们可以使用多级构建将这个二进制文件复制到目标体系结构的基本镜像中(如果是静态编译,也能使用 scratch),这样就完成了。然而,对于 Trow 注册中心,我想在最终的镜像中设置更多东西,所以最后阶段实际上开始于: FROM --platform=linux/arm/v7 debian:stable-slim 因此,我实际上混合使用了仿真和交叉编译——交叉编译用来创建二进制文件,仿真用来运行和配置最终的镜像。 3.清单列表 在上面关于仿真的建议中,你可能已经注意到:我们使用--platform参数来设置构建平台,但是我们在 FROM 行中将镜像指定为 debian:buster。这看起来似乎没有意义——平台当然依赖于基本镜像以及它是如何构建的,而不是用户之后的决定。 这样做是因为 Docker 使用了一种叫做清单列表的东西。对于给定镜像,这些列表包含指向不同体系结构镜像的指针。因为官方的 debian 镜像有一个定义好的清单列表,当我在笔记本上拉取这个镜像时,我会自动获得 amd64 镜像,当我在树莓派上拉取它时,我将得到 armv7 镜像。 为了让用户满意,我们可以为自己的镜像创建清单。如果我们回到前面的例子,首先我们需要重新构建并将镜像推送到一个镜像库: $ docker buildx build --platform linux/arm/v7 -t amouat/arch-test:armv7 . … $ docker push amouat/arch-test:armv7 … $ docker buildx build -t amouat/arch-test:amd64 . … $ docker push amouat/arch-test:amd64 接下来,我们创建一个清单列表指向这两个单独的镜像,并推送它们: $ docker manifest create amouat/arch-test:blog amouat/arch-test:amd64 amouat/arch-test:armv7 Created manifest list docker.io/amouat/arch-test:blog $ docker manifest push amouat/arch-test:blog sha256:039dd768fc0758fbe82e3296d40b45f71fd69768f21bb9e0da02d0fb28c67648 现在,Docker 将拉取并运行适合当前平台的镜像: $ docker run amouat/arch-test:blog Unable to find image 'amouat/arch-test:blog' locally blog: Pulling from amouat/arch-test Digest: sha256:039dd768fc0758fbe82e3296d40b45f71fd69768f21bb9e0da02d0fb28c67648 Status: Downloaded newer image for amouat/arch-test:blog x86_64 有树莓派的读者可以试着运行这个镜像,并确认它确实能在那个平台上工作!回顾一下:并不是 Docker 镜像的所有用户都运行 amd64。使用 buildx 和 QEMU,只需额外少量工作就可以为这些用户提供支持。 【云栖号在线课堂】每天都有产品技术专家分享!课程地址:https://yqh.aliyun.com/live 立即加入社群,与专家面对面,及时了解课程最新动态!【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK 原文发布时间:2020-04-14本文作者:Adrian Mouat 本文来自:“InfoQ 微信公众号”,了解相关信息可以关注“InfoQ”

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

WordPress调用置顶文章代码教程

WordPress调用置顶文章是常用的调用代码,码笔记分享WordPress调用置顶文章代码: WP调用置顶文章代码 以下代码为调用5篇置顶文章: <?php $sticky = get_option('sticky_posts'); rsort( $sticky ); $sticky = array_slice( $sticky, 0, 5); query_posts( array( 'post__in' => $sticky, 'caller_get_posts' => 1 ) ); if (have_posts()) : while (have_posts()) : the_post();?> <li><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></li> <?php endwhile; endif; ?> //码笔记:调用置顶文章代码 默认为调用5篇置顶文章,您可以修改$sticky, 0, 5中的数字来自定义调用置顶文章数量。

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

30 分钟快速入门 Docker 教程

原文地址:梁桂钊的博客 博客地址:http://blog.720ui.com 欢迎关注公众号:「服务端思维」。一群同频者,一起成长,一起精进,打破认知的局限性。 一、欢迎来到 Docker 世界 1. Docker 与虚拟化 在没有 Docker 的时代,我们会使用硬件虚拟化(虚拟机)以提供隔离。这里,虚拟机通过在操作系统上建立了一个中间虚拟软件层 Hypervisor ,并利用物理机器的资源虚拟出多个虚拟硬件环境来共享宿主机的资源,其中的应用运行在虚拟机内核上。但是,虚拟机对硬件的利用率存在瓶颈,因为虚拟机很难根据当前业务量动态调整其占用的硬件资源,因此容器化技术得以流行。其中,Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。 Docker 容器不使

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

Elasticsearch通关教程(一): 基础入门

简介 Elasticsearch是一个高度可扩展的、开源的、基于 Lucene 的全文搜索和分析引擎。它允许您快速,近实时地存储,搜索和分析大量数据,并支持多租户。 Elasticsearch也使用Java开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文搜索变得简单。 不过,Elasticsearch 不仅仅是 Lucene 和全文搜索,我们还能这样去描述它: 分布式的实时文件存储,每个字段都被索引并可被搜索 分布式的实时分析搜索引擎 可以扩展到上百台服务器,处理PB级结构化或非结构化数据 而且,所有的这些功能被集成到一个服务里面,你的应用可以通过简单的RESTful API、各种语言的客户端甚至命令行与之交互。 版本选择 在决定使用 Elasticsearch 的时候首先要考虑的是版本问题,Elasticsearch 目前有三个常用的稳定的主版本:2.x,5.x,6.x(排除 0.x 和 1.x)。 Elasticsearch 可以在这里查看所有历史版本,博主写这篇博文的时候最新的是 Elasticsearch 6.4.2。你可能会发现没有 3.x 和 4.x,ES 从 2.4.6 直接跳到了 5.0.0。这是为什么? 其实是为了ELK(ElasticSearch, logstash, kibana)技术栈的版本统一,免的给用户带来混乱。 我们知道 elasticsearch,kibana,logstash 都是 Elastic Stack 成员, 而且很多时候都是配合使用,那么为了协同开发,避免造成版本困惑,所以需要统一版本,至少保持在一个主版本号下。 在 Elasticsearch 是 2.x (2.x 的最后一版 2.4.6 的发布时间是 July 25, 2017) 的情况下,kibana 已经是 4.x(Kibana 4.6.5 的发布时间是 July 25, 2017),那么在 kibana 的下一主版本肯定是 5.x 了,所以 Elasticsearch 直接将自己的主版本发布为 5.0.0 了。统一之后,我们选版本就不会犹豫困惑了,我们选定 elasticsearch 的版本后再选择相同版本的 kibana 就行了,不用担忧版本不兼容的问题。 版本选择可以从以下几个方面考虑: 版本问题 2.x 版本较老,无法体验新功能,且性能不如 5.x。 6.x 版本有点新,网上资料相对比较少(开发时间充足的可以研究)。 数据迁移 2.x 版本数据可以直接迁移到 5.x; 5.X 版本的数据可以直接迁移到 6.x; 但是 2.x 版本数据无法直接迁移到 6.x。 周边工具 2.x 版本周边工具版本比较混乱;Kibana 等工具的对应版本需要自己查,不好匹配。 5.x 之后 Kibana 等工具的主版本号进行了统一。 Sql 语法支持 2.x,5.x,6.x 都可以安装 Elasticsearch-sql 插件,使用熟悉的SQL语法查询 Elasticsearch。 6.3.0 以后内置支持 SQL 模块,这个 SQL 模块是属于 X-Pack 的一部分。 通过以上的版本号了解之后,综合考虑,我起始选择了 elasticsearch 6.4.0版本,其实主要是因为它新,kibana 也选择了 kibana 6.4.0。但是等本地开发完成准备部署的时候,运维通知切换到5.6.0,因为公司其他部门的是5.6.0,方便统一维护,还好 API 变化不大。 环境搭建 安装 Elasticsearch Elasticsearch5.0之后的版本至少需要Java 8。可通过如下命令检查Java版本,然后根据需要进行相应的安装/升级。 java -version echo $ JAVA_HOME 你可以从 elastic.co/download 下载你需要的版本的Elasticsearch,解压之后即可使用。 如果是集群形式的,可在 ...\elasticsearch-5.6.0\config\elasticsearch.yml中配置一些你的集群信息: cluster.name: my-application # 集群名称 path.data: /path/to/data # ES数据存储路径 path.logs: /path/to/logs # ES日志存储路径 node.name: node-1 # 当前节点的名称 network.host: 192.168.0.1 # 配置当前结点绑定的IP地址,可设置为0.0.0.0 http.port: 9200 # 设置对外服务的HTTP端口,默认为9200 运行 Elasticsearch elasticsearch 准备好之后,在安装目录中执行以下命令可以启动运行: Linux ./bin/elasticsearch Windows D:\...\elasticsearch-6.4.0\bin\elasticsearch.bat 运行成功之后(启动日志里面会有.. started标志),浏览器访问http://localhost:9200/?pretty,你能看到类似以下返回信息(各版本稍微不同): { "name" : "AGXQ3qy", "cluster_name" : "elasticsearch", "cluster_uuid" : "mg9t4Yi2TRud1JNwRY0bPA", "version" : { "number" : "6.4.0", "build_flavor" : "default", "build_type" : "zip", "build_hash" : "595516e", "build_date" : "2018-08-17T23:18:47.308994Z", "build_snapshot" : false, "lucene_version" : "7.4.0", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" } 这说明你的 Elasticsearch 集群已经启动成功并且正常运行,接下来我们可以开始使用了。 可视化 web 界面 由于 Elasticsearch 的交互方式是 Rest 形式的,这种不是很直观方便,我们先安装图视化界面,方便我们操作。可选择的目前主要有 elasticsearch-head 和 kibana。 elasticsearch-head elasticsearch-head 是一个用于浏览和与 elasticsearch 集群交互的Web前端。elasticsearch-head 是 elasticsearch 集群管理、数据可视化、增删查改、查询语句可视化工具。elasticsearch head 是托管的,可以在 github 下载或 fork。 有两种运行和安装elasticsearch-head的方法: 作为ElasticSearch的插件运行(这是首选方法) elasticsearch/bin/elasticsearch-plugin -install mobz/elasticsearch-head。 open http://localhost:9200/_plugin/head/。 注意: 插件的安装方法,5.0之前为 plugin -install …,而在 5.0 以后为 elasticsearch-plugin -install …。 作为独立的webapp运行 git clone git://github.com/mobz/elasticsearch-head.git。 在浏览器中打开 index.html。现代浏览器需要使用 es-head。 默认情况下,es-head 将尝试连接到http:// localhost:9200 /的集群节点。在连接框中输入不同的节点地址,如果需要,单击“连接”。 成功后的界面如下,可以看到集群的状态信息: 由于 Head 安装起来比较麻烦( 需要安装 node.js ),网上资料也很多,所以我就不详细说了,更多信息可参考:elasticsearch-head kibana Kibana 和 elasticsearch 同属于 elastic 公司。 Kibana是一个开源分析和可视化平台,旨在与Elasticsearch协同工作。您使用Kibana搜索,查看和与存储在 Elasticsearch 索引中的数据进行交互。您可以轻松地执行高级数据分析,并在各种图表,表格和地图中可视化您的数据。 Kibana 使您可以轻松理解大量数据。其简单的基于浏览器的界面使您能够快速创建和共享动态仪表板,实时显示 Elasticsearch 查询的更改。 设置 Kibana 非常容易。您可以安装 Kibana 并在几分钟内开始探索您的 Elasticsearch 索引 - 无需代码,无需额外的基础架构。 同样可在 kibana 选择需要的对应版本(与 elasticsearch 版本对应),然后下载解压即可使用,具体步骤如下: 下载并解压缩 Kibana。 在编辑器中打开 config / kibana.yml。 设置 elasticsearch.url 为您的Elasticsearch实例,如本地:elasticsearch.url: "http://localhost:9200"。 运行 bin/kibana(或binkibana.bat在Windows上)。 浏览器输入 http:// localhost:5601。 如果运行成功,但是无法访问,可以关闭防火墙再试试。 基本概念 一切准备就绪,我们正式操作之前,先来了解一些 ES 的核心基本概念,从一开始就理解这些概念将极大地帮助简化学习过程。 Elasticsearch是一个近乎实时(NRT)的搜索平台。这意味着从索引文档到可搜索文档的时间有一点延迟(通常是一秒)。通常有集群,节点,分片,副本等概念。 集群(Cluster) 集群(cluster)是一组具有相同cluster.name的节点集合,他们协同工作,共享数据并提供故障转移和扩展功能,当然一个节点也可以组成一个集群。 集群由唯一名称标识,默认情况下为“elasticsearch”。此名称很重要,因为如果节点设置为按名称加入集群的话,则该节点只能是集群的一部分。 确保不同的环境中使用不同的集群名称,否则最终会导致节点加入错误的集群。 【集群健康状态】 集群状态通过 绿,黄,红 来标识 绿色 - 一切都很好(集群功能齐全)。 黄色 - 所有数据均可用,但尚未分配一些副本(集群功能齐全)。 红色 - 某些数据由于某种原因不可用(集群部分功能)。 注意:当群集为红色时,它将继续提供来自可用分片的搜索请求,但您可能需要尽快修复它,因为存在未分配的分片。 要检查群集运行状况,我们可以在 Kibana 控制台中运行以下命令GET /_cluster/health,得到如下信息: { "cluster_name": "elasticsearch", "status": "yellow", "timed_out": false, "number_of_nodes": 1, "number_of_data_nodes": 1, "active_primary_shards": 28, "active_shards": 28, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 5, "delayed_unassigned_shards": 0, "number_of_pending_tasks": 0, "number_of_in_flight_fetch": 0, "task_max_waiting_in_queue_millis": 0, "active_shards_percent_as_number": 84.84848484848484 } 节点(Node) 节点,一个运行的 ES 实例就是一个节点,节点存储数据并参与集群的索引和搜索功能。 就像集群一样,节点由名称标识,默认情况下,该名称是在启动时分配给节点的随机通用唯一标识符(UUID)。如果不需要默认值,可以定义所需的任何节点名称。此名称对于管理目的非常重要,您可以在其中识别网络中哪些服务器与 Elasticsearch 集群中的哪些节点相对应。 可以将节点配置为按集群名称加入特定集群。默认情况下,每个节点都设置为加入一个名为 cluster 的 elasticsearch 集群,这意味着如果您在网络上启动了许多节点并且假设它们可以相互发现 - 它们将自动形成并加入一个名为 elasticsearch 的集群。 索引(Index) 索引是具有某些类似特征的文档集合。例如,您可以拥有店铺数据的索引,商品的一个索引以及订单数据的一个索引。 索引由名称标识(必须全部小写),此名称用于在对其中的文档执行索引,搜索,更新和删除操作时引用索引。 类型(Type) 类型,曾经是索引的逻辑类别/分区,允许您在同一索引中存储不同类型的文档,例如,一种类型用于用户,另一种类型用于博客帖子。 在 6.0.0 中弃用,以后将不再可能在索引中创建多个类型,并且将在更高版本中删除类型的整个概念。 文档(Document) 文档是可以建立索引的基本信息单元。例如,您可以为单个客户提供文档,为单个产品提供一个文档,为单个订单提供一个文档。该文档以JSON(JavaScript Object Notation)表示,JSON是一种普遍存在的互联网数据交换格式。 在索引/类型中,您可以根据需要存储任意数量的文档。请注意,尽管文档实际上驻留在索引中,但实际上必须将文档编入索引/分配给索引中的类型。 分片(Shards) 索引可能存储大量可能超过单个节点的硬件限制的数据。例如,占用1TB磁盘空间的十亿个文档的单个索引可能不适合单个节点的磁盘,或者可能太慢而无法单独从单个节点提供搜索请求。 为了解决这个问题,Elasticsearch 提供了将索引细分为多个称为分片的功能。创建索引时,只需定义所需的分片数即可。每个分片本身都是一个功能齐全且独立的“索引”,可以托管在集群中的任何节点上。 设置分片的目的及原因主要是: 它允许您水平拆分/缩放内容量 它允许您跨分片(可能在多个节点上)分布和并行化操作,从而提高性能/吞吐量 分片的分布方式以及如何将其文档聚合回搜索请求的机制完全由 Elasticsearch 管理,对用户而言是透明的。 在可能随时发生故障的网络/云环境中,分片非常有用,建议使用故障转移机制,以防分片/节点以某种方式脱机或因任何原因消失。为此,Elasticsearch 允许您将索引的分片的一个或多个副本制作成所谓的副本分片或简称副本。 副本(Replicasedit) 副本,是对分片的复制。目的是为了当分片/节点发生故障时提供高可用性,它允许您扩展搜索量/吞吐量,因为可以在所有副本上并行执行搜索。 总而言之,每个索引可以拆分为多个分片。索引也可以复制为零次(表示没有副本)或更多次。复制之后,每个索引将具有主分片(从原始分片复制而来的)和复制分片(主分片的副本)。 可以在创建索引时为每个索引定义分片和副本的数量。创建索引后,您也可以随时动态更改副本数。您可以使用_shrink 和 _splitAPI 更改现有索引的分片数,但这不是一项轻松的任务,所以预先计划正确数量的分片是最佳方法。 默认情况下,Elasticsearch 中的每个索引都分配了5个主分片和1个副本,这意味着如果集群中至少有两个节点,则索引将包含5个主分片和另外5个副本分片(1个完整副本),总计为每个索引10个分片。 小结 我们假设有一个集群由三个节点组成(Node1 , Node2 , Node3)。 它有两个主分片(P0 , P1),每个主分片有两个副本分片(R0 , R1)。相同分片的副本不会放在同一节点,所以我们的集群看起来如下图所示 “有三个节点和一个索引的集群”。 类似于关系型数据库:数据库集群,假如有个用户表,我担心数据量过大,我新建了多个用户表(即 Shard),将用户信息数据切分成多份,然后根据某种规则分到这些用户表中,我又担心某个表会出现异常造成数据丢失,我又将每个表分别备份了一次(即 Replica )。 副本是乘法,越多越浪费,但也越保险。分片是除法,分片越多,单分片数据就越少也越分散。 另外,我们可以画一个对比图来类比传统关系型数据库: 关系型数据库 -> Databases(库) -> Tables(表) -> Rows(行) -> Columns(列)。 Elasticsearch -> Indeces(索引) -> Types(类型) -> Documents(文档) -> Fields(属性)。 Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型 (Types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。 虽然这么类比,但是毕竟是两个差异化的产品,而且上面也说过在以后的版本中类型 (Types) 可能会被删除,所以一般我们创建索引都是一个种类对应一个索引。生鲜就创建商品的索引,生活用品就创建生活用品的索引,而不会说创建一个商品的索引,里面既包含生鲜的类型,又包含生活用品的类型。 而且你可能已经注意到索引(index)这个词在Elasticsearch中有着不同的含义,所以有必要在此做一下区分: 「索引」含义的区分 索引(名词) 如上文所述,一个索引(index)就像是传统关系数据库中的数据库,它是相关文档存储的地方,index的复数是 indices 或 indexes。 索引(动词) 「索引一个文档」表示把一个文档存储到索引(名词)里,以便它可以被检索或者查询。这很像SQL中的INSERT关键字,差别是,如果文档已经存在,新的文档将覆盖旧的文档。 倒排索引 传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。 与Elasticsearch交互 目前与 elasticsearch 交互主要有两种方式:Client API 和 RESTful API。 Client API方式: Elasticsearch 为以下语言提供了官方客户端 --Groovy、JavaScript、.NET、 PHP、 Perl、 Python 和 Ruby--还有很多社区提供的客户端和插件,所有这些都可以在 Elasticsearch Clients 中找到。后面再开一篇来详细说明。 RESTful API with JSON over HTTP: 所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用 curl 命令来和 Elasticsearch 交互。 一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成: curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>' 被 < > 标记的部件: 数据格式 在应用程序中对象很少只是一个简单的键和值的列表。通常,它们拥有更复杂的数据结构,可能包括日期、地理信息、其他对象或者数组等。 也许有一天你想把这些对象存储在数据库中。使用关系型数据库的行和列存储,这相当于是把一个表现力丰富的对象挤压到一个非常大的电子表格中:你必须将这个对象扁平化来适应表结构,通常一个字段对应一列,而且又不得不在每次查询时重新构造对象。 Elasticsearch 是面向文档的,意味着它存储整个对象或文档。Elasticsearch 不仅存储文档,而且 每个文档的内容可以被检索。在 Elasticsearch 中,你对文档进行索引、检索、排序和过滤而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。 Elasticsearch 使用 JavaScript Object Notation 或者 JSON 作为文档的序列化格式。JSON 序列化被大多数编程语言所支持,并且已经成为 NoSQL 领域的标准格式。 它简单、简洁、易于阅读。几乎所有的语言都有相应的模块可以将任意的数据结构或对象 转化成 JSON 格式,只是细节各不相同。 { "_index" : "megacorp", "_type" : "employee", "_id" : "1", "_version" : 1, "found" : true, "_source" : { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] } } 索引的应用 一切准备就绪之后我们开始来使用起来,体验 ElasticSearch 的世界。首先,我们来查看我们的所有索引信息: GET _search { "query": { "match_all": {} } } 得到如下结果信息: { "took": 0, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": ".kibana", "_type": "config", "_id": "5.6.0", "_score": 1, "_source": { "buildNum": 15523 } } ] } } 可以发现,当前只有一个索引,是.kibana,当然这不是我们自己的,这是kibana的。 创建第一个简单索引 NBA的新的赛季又开始了,我相信大部分人有精彩比赛的时候还是会去关注的,我们创建一个 NBA 球队的索引,开始我们的学习之路,索引名称需是小写。 PUT nba { "settings":{ "number_of_shards": 3, "number_of_replicas": 1 }, "mappings":{ "nba":{ "properties":{ "name_cn":{ "type":"text" }, "name_en":{ "type":"text" }, "gymnasium":{ "type":"text" }, "topStar":{ "type":"text" }, "championship":{ "type":"integer" }, "date":{ "type":"date", "format":"yyyy-MM-dd HH:mm:ss|| yyy-MM-dd||epoch_millis" } } } } } 字段说明: 字段名称 字段说明 nba 索引 number_of_shards 分片数 number_of_replicas 副本数 name_cn 球队中文名 name_en 球队英文名 gymnasium 球馆名称 championship 总冠军次数 topStar 当家球星 date 加入NBA年份 如果格式书写正确,我们会得到如下返回信息,表示创建成功 { "acknowledged": true, "shards_acknowledged": true, "index": "nba" } 新增索引数据 索引创建完成之后,我们往索引中加入球队数据,1,2,3 是我们指定的 ID,如果不写 ES 会默认ID。 其实我们可以不创建上面的索引 mapping 直接推送数据,但是这样 ES 会根据数据信息自动为我们设定字段类型,这会造成索引信息不准确的风险。 PUT /nba/nba/1 { "name_en":"San Antonio Spurs SAS", "name_cn":"圣安东尼安马刺", "gymnasium":"AT&T中心球馆", "championship": 5, "topStar":"蒂姆·邓肯", "date":"1995-04-12" } PUT /nba/nba/2 { "name_en":"Los Angeles Lakers", "name_cn":"洛杉矶湖人", "gymnasium":"斯台普斯中心球馆", "championship": 16, "topStar":"科比·布莱恩特", "date":"1947-05-12" } PUT /nba/nba/3 { "name_en":"Golden State Warriors", "name_cn":"金州勇士队", "gymnasium":"甲骨文球馆", "championship": 6, "topStar":"斯蒂芬·库里", "date":"1949-06-13" } PUT /nba/nba/4 { "name_en":"Miami Heat", "name_cn":"迈阿密热火队", "gymnasium":"美国航空球场", "championship": 3, "topStar":"勒布朗·詹姆斯", "date":"1988-06-13" } PUT /nba/nba/5 { "name_en":"Cleveland Cavaliers", "name_cn":"克利夫兰骑士队", "gymnasium":"速贷球馆", "championship": 1, "topStar":"勒布朗·詹姆斯", "date":"1970-06-13" } 索引数据 PUT 成功,会返回如下信息 { "_index": "nba", "_type": "nba", "_id": "1", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "created": true } 查询索引数据 上面新增完数据之后,这时候我们再执行开始的 MATCH_ALL ,就会发现我们自己的索引信息也在查询的结果里面了,只是查询的结果是全部信息,其中包括索引、分片和副本的信息,内容比较多。我们可单独查询自己需要的索引信息。 Elasticsearch 提供丰富且灵活的查询语言叫做 DSL 查询 (Query DSL) ,它允许你构建更加复杂、强大的搜索。 1.匹配查询 match,match_all 我们尝试一个最简单的搜索全部员工的请求: # 查询全部球队的信息 GET /nba/nba/_search { "query": { "match_all": {} } } 得到的查询结果如下 { "took": 4, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 3, "max_score": 1, "hits": [ { "_index": "nba", "_type": "nba", "_id": "2", "_score": 1, "_source": { "name_en": "Los Angeles Lakers", "name_cn": "洛杉矶湖人", "gymnasium": "斯台普斯中心球馆", "championship": 16, "topStar": "科比·布莱恩特", "date": "1947-05-12" } }, { "_index": "nba", "_type": "nba", "_id": "1", "_score": 1, "_source": { "name_en": "San Antonio Spurs SAS", "name_cn": "圣安东尼安马刺", "gymnasium": "AT&T中心球馆", "championship": 5, "topStar": "蒂姆·邓肯", "date": "1995-04-12" } }, { "_index": "nba", "_type": "nba", "_id": "3", "_score": 1, "_source": { "name_en": "Golden State Warriors", "name_cn": "金州勇士队", "gymnasium": "甲骨文球馆", "championship": 6, "topStar": "斯蒂芬·库里", "date": "1949-06-13" } ··· } ] } } 响应的数据结果分为两部分 { ----------------first part-------------------- "took": 0, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, ---------------second part--------------------- "hits": { "total": 0, "max_score": null, "hits": [] } } 第一部分为:分片副本信息,第二部分 hits 包装的为查询的数据集。 注意:响应内容不仅会告诉我们哪些文档被匹配到,而且这些文档内容完整的被包含在其中—我们在给用户展示搜 索结果时需要用到的所有信息都有了。 # 查询英文名称为:"Golden State Warriors" 的球队信息 GET /nba/nba/_search { "query": { "match": { "name_en": "Golden State Warriors" } } } 可得到的查询结果为: { "took": 6, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1.9646256, "hits": [ { "_index": "nba", "_type": "nba", "_id": "3", "_score": 1.9646256, "_source": { "name_en": "Golden State Warriors", "name_cn": "金州勇士队", "gymnasium": "甲骨文球馆", "championship": 6, "topStar": "斯蒂芬·库里", "date": "1949-06-13" } } ] } } 2.过滤查询 Filter 我们让搜索变的复杂一些。我们想要找到当家球星是勒布朗·詹姆斯,但是我们只想得到总冠军多余1次的球队。我们的语句将做一些改变用来添加过滤器(filter),它允许我们有效的执行一个结构化搜索: GET /nba/nba/_search { "query": { "bool": { "filter": { "range": { "championship": { "gt": 1 } } }, "must": { "match": { "topStar": "勒布朗·詹姆斯" } } } } } 我们发现每次查询,查询结果里面都有一个 _score字段,一般Elasticsearch根据相关评分排序,相关评分是根据文档与语句的匹配度来得出, _score值越高说明匹配度越高。 Elasticsearch如何进行全文字段搜索且首先返回相关性性最大的结果。相关性(relevance)概念在Elasticsearch中非常重要,而这也是它与传统关系型数据库中记录只有匹配和不匹配概念最大的不同。 结束语 由于篇幅限制,对于 ElasticSearch 最基本的概念暂时先介绍这么多,要写的内容还很多,经过接近一个月的技术调研和开发,目前对于 ES 也有一个总体的技术了解,但是很多细节还是需要琢磨的,ES 的功能确实强大且丰富,要想熟练耍起来,还是需要一定时间的。 后面会继续介绍 ES的相关内容,大概包括 ES 服务的 Java 语言搭建,ES 的 SQL方式查询等等内容。有兴趣的可以先关注本人的博客,由于质量要求大概一星期更新一篇。 另外,我这里添加一个园友ReyCG对本篇文章的思维导图总结,通过该思维导图我们可以更加清晰的理解Elasticsearch的基础信息。

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

unity跨平台sqlite使用教程

最近做的一个新项目,需要处理大量数据和动态图表展示。 并且结合跨平台使用的问题,考虑再三,计划使用Unity3D+SQLite进行开发。 因为跨平台的需求,先忽略UnityStore的收费SQLite插件。在GitHub上找到了“SQLiteUnityKit”。 SQLiteUnityKit 全平台支持,包括iOS, Android, MAC 还有 Windows。 亲测windows、MAC和Android都可正常使用。IOS目前没有开发账号,所以作罢。 android测试成功.jpg android测试成功.jpg 安装SQLite 可以只安装命令行环境,但是安装可视化客户端可以更方便的使用数据库。 下面是我推荐的客户端,DB Browser。轻巧、跨平台,使用方便。 推荐客户端DB Browser 下载好后正常安装即可。 创建数据库 打开DB Browser。 点击“新建数据库”按钮新建数据库,命名为test.db。 随后出现“编辑表定义”窗口。 表名称设为“example” 点击“添加字段”按钮三次,添加三个字段。 第一个:名称为“id”,类型为“INTEGER”,勾选PK(主键)和AI(自动增值)用作每个数据的唯一索引。 后面两个字段不勾选选框,只改名称和类型。 第二个:名称为“name”,类型为“TEXT”。 第三个:名称“dummy”,类型为“INTEGER”。 点击“OK”按钮完成“test.db”数据库的创建。 可以顺便给里面添加一两行数据作测试用。 或者直接命令行运行SQLite 创建文件 表定义 如果希望用其它方式安装SQLite和创建测试数据库,或者学习sqlite语法。可在网上查找,资料很多。 SQLiteUnityKit下载 GitHub对应页面 不过SQLiteUnityKit 并未添加windows支持的"SQLite3.dll"文件。 所以需要windows下使用则自己下一个: windows平台SQLite3.dll下载地址 请根据自己的unity是x64还是x86酌情下载对应dll。 更多unity2018的功能介绍请到paws3d学习中心查找。

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

老蔡: Docker学习教程-基础(01)

Docker基础学习 Docker简介 开发人员使用了 Docker,就不必安装和配置复杂的数据库, 也无需在不兼容语言工具链版本之间切换时担心。 应用容器化之后,其复杂性就被转移到能够轻松构建、共享和运行的容器中。当有新同事安排到新的代码库时, 无需再费时费力地安装软件和解释设置过程。 以 Dockerfile 文件形式发布的代码使用起来非常简单:首先安装 Docker 和编辑器, 然后拉取作为 Docker 镜像打包在一起的依赖资源,短短数分钟,就能够构建和调试应用了。 Docker版本 DockerEE企业版, 收费 DockerCE社区版, 免费(推荐) Docker相关链接 Docker英文官网: https://www.docker.com/ Docker中文官网(更新日期17年6月): https://www.docker-cn.com/ Docker云仓库: https://hub.docker.com/ Docker安装 docker能在多种平台上运行, 本文章主要介绍Centos7.0系统版本的安装,若您想学习其他系统平台的安装, 可移步至官方文档: https://docs.docker-cn.com/docker-for-mac/install/ centos7安装Docker步骤: 操作系统要求如需安装 Docker CE,您需要 64 位版本的 CentOS 7。 1. 卸载旧版本Docker 的早期版本称为 docker 或 docker-engine。如果安装了这些版本,请卸载它们及关联的依赖资源。 $ sudo yum remove docker \ docker-common \ docker-selinux \ docker-engine 如果 yum 报告未安装任何这些软件包,这表示情况正常。将保留 /var/lib/docker/ 的内容,包括镜像、容器、存储卷和网络。 2. 安装 Docker CE 2.1 安装所需的软件包。yum-utils 提供了 yum-config-manager 实用程序,并且 devicemapper 存储驱动需要 device-mapper-persistent-data 和 lvm2。 $ sudo yum install -y yum-utils device-mapper-persistent-data lvm2 2.2 使用下列命令设置 stable 镜像仓库。您始终需要使用 stable 镜像仓库,即使您还需要通过 edge 或 testing 镜像仓库安装构建也是如此。 $ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo 2.3 更新 yum 软件包索引。 $ sudo yum makecache fast 2.4 安装Docker $ sudo yum install docker-ce 卸载 Docker CE 卸载 Docker 软件包: $ sudo yum remove docker-ce 主机上的镜像、容器、存储卷、或定制配置文件不会自动删除。如需删除所有镜像、容器和存储卷,请运行下列命令: $ sudo rm -rf /var/lib/docker 您必须手动删除任何已编辑的配置文件。 Docker开启停止重启命令 # 开启 $ sudo systemctl start docker # 停止 $ sudo systemctl stop docker #重启 $ sudo systemctl retstart docker

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

Android教程 如何免费使用SMSSDK

获取mob的appkeyhttp://bbs.mob.com/forum.php?mod=viewthread&tid=8212&extra=page%3D1一、配置gradle1、打开项目根目录的build.gradle,在buildscrip–>dependencies 模块下面添加 classpath ‘com.mob.sdk:MobSDK:+’,如下所示; buildscript { repositories { jcenter() } dependencies { ... classpath 'com.mob.sdk:MobSDK:+' } } 2、在使用SMSSDK模块的build.gradle中,添加MobSDK插件和扩展,如: // 添加插件 apply plugin: 'com.mob.sdk' // 在MobSDK的扩展中注册SMSSDK的相关信息 MobSDK { appKey "d580ad56b4b5" appSecret "7fcae59a62342e7e2759e9e397c82bdd" SMSSDK {} } 二、添加代码1、初始化MobSDK如果您没有在AndroidManifest中设置appliaction的类名,MobSDK会将这个设置为com.mob.MobApplication,但如果您设置了,请在您自己的Application类中调用: MobSDK.init(this); 以初始化MobSDK。2、发送验证码并取得验证结果(如果提示489错误MD5错误请点击这里)有两种方法完成验证码短信的发送和验证:调用可视化界面和使用无界面接口2-1、以可视化界面完成操作 public void sendCode(Context context) { RegisterPage page = new RegisterPage(); //如果使用我们的ui,没有申请模板编号的情况下需传null page.setTempCode(null); page.setRegisterCallback(new EventHandler() { public void afterEvent(int event, int result, Object data) { if (result == SMSSDK.RESULT_COMPLETE) { // 处理成功的结果 HashMap<String,Object> phoneMap = (HashMap<String, Object>) data; String country = (String) phoneMap.get("country"); // 国家代码,如“86” String phone = (String) phoneMap.get("phone"); // 手机号码,如“13800138000” // TODO 利用国家代码和手机号码进行后续的操作 } else{ // TODO 处理错误的结果 } } }); page.show(context); } 2-2、以无界面接口完成操作 // 在尝试读取通信录时以弹窗提示用户(可选功能) SMSSDK.setAskPermisionOnReadContact(true); EventHandler eventHandler = new EventHandler() { public void afterEvent(int event, int result, Object data) { // afterEvent会在子线程被调用,因此如果后续有UI相关操作,需要将数据发送到UI线程 Message msg = new Message(); msg.arg1 = event; msg.arg2 = result; msg.obj = data; new Handler(Looper.getMainLooper(), new Callback() { @Override public boolean handleMessage(Message msg) { int event = msg.arg1; int result = msg.arg2; Object data = msg.obj; if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) { if (result == SMSSDK.RESULT_COMPLETE) { // TODO 处理成功得到验证码的结果 // 请注意,此时只是完成了发送验证码的请求,验证码短信还需要几秒钟之后才送达 } else { // TODO 处理错误的结果 ((Throwable) data).printStackTrace(); } } else if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) { if (result == SMSSDK.RESULT_COMPLETE) { // TODO 处理验证码验证通过的结果 } else { // TODO 处理错误的结果 ((Throwable) data).printStackTrace(); } } // TODO 其他接口的返回结果也类似,根据event判断当前数据属于哪个接口 return false; } }).sendMessage(msg); } }; // 注册一个事件回调,用于处理SMSSDK接口请求的结果 SMSSDK.registerEventHandler(eventHandler); // 请求验证码,其中country表示国家代码,如“86”;phone表示手机号码,如“13800138000” SMSSDK.getVerificationCode(country, phone); // 提交验证码,其中的code表示验证码,如“1357” SMSSDK.submitVerificationCode(country, phone, code); // 使用完EventHandler需注销,否则可能出现内存泄漏 protected void onDestroy() { super.onDestroy(); SMSSDK.unregisterEventHandler(eventHandler); } 三、混淆设置SMSSDK已经做了混淆处理,再次混淆会导致不可预期的错误,请在您的混淆脚本中添加如下的配置,跳过对SMSSDK的混淆操作: -keep class com.mob.**{*;} -keep class cn.smssdk.**{*;} -dontwarn com.mob.** 四、注意事项 SMSSDK默认会添加一套开源的GUI库,如果您不需要这个库,可以在SMSSDK下设置“gui false”来关闭它 MobSDK默认为SMSSDK提供最新版本的集成,如果您想锁定某个版本,可以在SMSSDK下设置“version “某个版本””来固定使用这个版本 如果使用MobSDK的模块会被其它模块依赖,请确保依赖它的模块也引入MobSDK插件,或在此模块的gradle中添加: repositories { jcenter() }

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

Spring Boot教程全集-修正集合

修正1:20 使用Caching-Redis 位置:com.roncoo.education.cache.impl.RoncooUserLogCacheImpl,第34行,@CachePut(key = "#p0") 正确:@CachePut(key = "#p0.id") 原因:key值定义写错。#p0是指使用第一个参数作为key值,上面selectById是将主键作为key,如果更新将对象作为key,则会导致更新之后,查找不到最新的信息,对象作为key,因为修改,会每修改一次都产生一条记录,因为每个对象的属性都会变化 感谢学员(你的微笑、很美)的发现。 修正2:31 生产部署-注意事项和如何使用脚本 位置:kill -9 ${procedure}(第一个kill的位置) 正确:kill ${procedure} 原因:kill -9 是立即杀死应用,第一关闭的时候,不应该是杀死,这样就无法令spring boot应用进行优雅关机,当kill不成功的时候,才考虑进行kill -9。

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

Redis入门教程(C#)

Redis是什么? Redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。 补充概念: 持久化:是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持久化至数据库中,能够长久保存) Redis的安装、启动: 下载地址:https://github.com/MSOpenTech/redis/releases,可根据需要选择下载32位或者64位 这里我选择的是64位安装包: 然后解压安装包到指定目录。 接下来是Rdis的启动,打开一个cmd命令窗口,进入解压后的Redis目录,运行命令"redis-server.exe redis.windows.conf"即可启动Redis,启动后界面如下: 接下来介绍Redis的简单使用: 1.在VS 2017上新建一个项目,我这里创建的是控制台程序; 2.通过NuGet管理器安装ServiceStack.Redis库 3.新建一个测试类: public class Todo { public long Id { get; set; } public string Content { get; set; } public int Order { get; set; } public bool Done { get; set; } } 4.测试代码如下,此过程中不能关闭之前的cmd窗口,不然会无法访问服务器: static void Main(string[] args) { var redisManger = new RedisManagerPool("127.0.0.1:6379"); //Redis的连接字符串 var redis = redisManger.GetClient(); //获取一个Redis Client var redisTodos = redis.As<Todo>(); var newTodo = new Todo //实例化一个Todo类 { Id = redisTodos.GetNextSequence(), Content = "Learn Redis", Order = 1, }; redisTodos.Store(newTodo); //把newTodo实例保存到数据库中 增 Todo saveTodo = redisTodos.GetById(newTodo.Id); //根据Id查询 查 "Saved Todo: {0}".Print(saveTodo.Dump()); saveTodo.Done = true; //改 redisTodos.Store(saveTodo); var updateTodo = redisTodos.GetById(newTodo.Id); //查 "Updated Todo: {0}".Print(updateTodo.Dump()); redisTodos.DeleteById(newTodo.Id); //删除 var remainingTodos = redisTodos.GetAll(); "No more Todos:".Print(remainingTodos.Dump()); Console.ReadLine(); } 最终运行结果如下:

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册