Elasticsearch 处理地理信息

1、GeoHash

​ GeoHash是一种地理坐标编码系统,可以将地理位置按照一定的规则转换为字符串,以方便对地理位置信息建立空间索引。首先要明确的是,GeoHash代表的不是一个点而是一个区域。GeoHash具有两个显著的特点:一是通过改变 GeoHash的长度,我们可以表示任意精度的位置:GeoHash越短,其表示的区域越大,位置精度越低;相反,GeoHash越长,其表示的区域越小,位置精度越高。Elasticsearch 支持GeoHash字符串长度是12,这个精度已经达到了厘米级别;二是如果不同位置的GeoHash字符串前缀相同,那他们一定在同一个区域中。

​ GeoHash将地理坐标编码为字符串的方法与二分查找有几分相识。它将经纬度范围一分为二,分成左右两个区间;坐标落入左区间为0,落入右区间为1。按照此方法,分别对精度和维度不停地地柜逼近实际坐标值,就会得到两组由0,1组成的数字字符串。然后按照偶数位放经度,奇数位放纬度的方法,将两组数据串联组合起来。最后将组合的数字串转换成十进制,并用Base32对数字进行编码就得到GeoHash最终编码了。

​ 根据经纬度的定义,经度整体范围为: [ -180 , 180 ] ,纬度整体范围为:[ -90 , 90 ]。所以第一次递归分割坐标后,经度的左右区间为 **[ -180 , 0 ) **和

[ 0 , 180 ],即西半球和东半球 纬度的左右区间为 **[ -90 , 0 ) [ 0 , 90 ],即南半球和北半球。以山东济南某地坐标( 117.15838 , 36.74038 )**为例,经纬度第一次递归后都落入到右区间,则他们第一位数字都是1。由于落入了右区间,所以经纬第二次递归就是针对右区间分割:经度为 **[ 0 , 90 ) **和 [ 90 , 180 ],纬度为

[ 0 , 45 ) [ 45 , 90 ] 。这次经度落入到了右区间,二纬度落入了左区间,所以他们的第二位数字分别为10。按照此方法不停的递归下去,就能无线的接近于实际坐标。

​ 可以看出,GeoHash时间上是将地球假设为一个平面,然后在这个平面上划分网格的过程。在这个递归的过程中,每一次都是将整个区域一分为二,区域面积也就约分越小,而且在相同区域的位置他们的前缀数字一定是相同的。表1-1列出了经度 117.15838经过十次递归运算过程及结果。

表1-1 GeoHash经度 117.15838

次数经度范围左区间 - 0右区间 - 1117.15838
1[ -180 , 180 ][ -180 , 0 )[ 0 , 180 ]1
2[ 0 , 180 ][ 0 , 90 )[ 90 , 180 ]1
3[ 90 , 180 ][90 , 135 )[ 135 , 180 ]0
4[ 90 , 135 )[ 90, 112.5 )[ 112.5 , 135 )1
5[ 112.5 , 135 )[ 112.5 , 123.75 )[ 123.75 , 135 )0
6[ 112.5 , 123.75 )[ 112.5 , 118.125 )[ 118.125 , 123.75)0
7[ 112.5 , 118.125 )[ 112.5 , 115.3125 )[ 115.3125 , 118.125)1
8[ 115.3125 , 118.125)[ 115.3125 , 116.71875 )[ 116.71875 , 118.125 )1
9[ 116.71875 , 118.125 )[ 116.71875 , 117.421875 )[ 117.421875 , 118.125 )0
10[ 116.71875 , 117.421875 )[ 116.71875 ,117.0703125 )[ 117.0703125, 117.421875 )1

​ 经过10次递归,经度为117.15838得到的数字字符串为1101001101,以同样的方式对纬度做GeoHash运算,表1-2列出了纬度 36.74038经过十次递归运算过程及结果。

表1-2 GeoHash纬度 36.74038

次数经度范围左区间 - 0右区间 - 136.74038
1[ -90, 90][ -90 , 0 )[ 0 , 90]1
2[ 0 , 90][ 0 , 45)[ 45, 90]0
3[ 0 , 45)[0, 22.5)[ 22.5, 45 )1
4[ 22.5, 45)[ 22.5, 33.75 )[ 33.75 , 45)1
5[ 33.75 , 45)[ 33.75, 39.375 )[ 39.375 , 45 )0
6[ 33.75, 39.375 )[ 33.75, 36.5625 )[ 36.5625 , 39.375)1
7[ 36.5625 , 39.375)[ 36.5625 , 37.96875)[ 37.96875 , 39.375)0
8[ 36.5625 , 37.96875)[ 36.5625 , 37.265625 )[ 37.265625 , 37.96875 )0
9[ 36.5625 , 37.265625 )[ 36.5625, 36.9140625 )[ 36.9140625 , 37.265625 )0
10[ 36.5625, 36.9140625 )[ 36.5625 ,36.7385625 )[ 36.7385625 , 36.9140625 )1

同样经过十次递归,纬度得到的数字串为1011010001 ,下面按偶数位经度,奇数位纬度的方法合并两个数字串,注意位数是从0开始,或者理解为先经度后纬度,各区一位交叉合并。

经度:1101001101

纬度:1011010001

合并:11100 11100 01101 00011

合并后结果按照每五位一组,一次转换成十进制数 28、28、13、3,并使用表1-3对应的Base32编码转为字符串。

表 1- 3
在这里插入图片描述

​ 最终结果为wwe34,可以到 http://geohash.org/ 网站上输入"36.74038,117.15838" 验证结果为:wwe3402hhp5z 这个结果为12位,说明做了30次递归。

表1-4列出了GeoHash字符串长度与实际位置误差关系。

表 1- 4 GeoHash字符串长度与实际位置关系

GeoHash长度纬度位数经度位数纬度误差经度误差区域面积
123±23±235009.4km*4992.6km
255±2.8±5.61252.3km*624.1km
378±0.70±0.70156.5km*156km
41010±0.087±0.1839.1km*19.5km
51213±0.022±0.0224.9km*4.9km
61515±0.0027±0.00551.2km*609.4m
71718±0.00068±0.00068152.9m*152.4m
82020±0.000085±0.0001738.2m*19m
92223±0.000021±0.0000214.8m*4.8m
102525±0.00000268±0.000005361.2m*59.5cm
112728±0.00000067±0.000000674.9cm*14.9cm
123030±0.00000008±0.000000173.7cm*1.9cm

​ 根据图1-4表示,当GeoHash字符串长度达到12位时,位置经度误差可以控制在不到8cm²的范围内。

2、地理类型字段

​ Elasticsearch 提供了两种地理相关的数据类型geo_pointgeo_shape,前者用于保存地理位置,即具体的某一个坐标;而后者用于保存地理形状,如矩形和多边形。

1. geo_point 类型

​ 地理位置由经度和维度共同定义,所以geo_point定义地理位置坐标最基本的形式也是通过提供经度和纬度来实现的。

如下:存储了数据的日期、主键、地理位置信息

PUT /obd
{"mapping":{"properties":{"datadate": {  //数据日期"type": "date"},"id": {   //数据主键"type": "long"},"location": {  //地理位置信息"type": "geo_point"},"name": {  //名称(编号)"type": "text"}}}
}

​ 如上,location的数据类型为geo_point,这种类型有四种表示形式

​ 例如:

# 格式1 对象
PUT /obd/_doc/1
{"location": { "lat": 41.12,"lon": -71.34}
}
# 格式2 数组
PUT /obd/_doc/2
{"location": [ -71.34, 41.12 ] 
}
# 格式3 字符串
PUT /obd/_doc/3
{"location": "41.12,-71.34" 
}
# 格式4 geohash
PUT /obd/_doc/4
{"location": "wwe3402hhp5z" 
}

2、基于geo_point类型的查询(java)

  • 按距离搜索

  • 按距离排序

  • 按时间范围

maven依赖

   <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.3</version><relativePath/> <!-- lookup parent from repository --></parent>
<dependencies><!--必备: spring boot web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--es--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><!--测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--数据库--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>mssql-jdbc</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--mybatis--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><!-- druid 连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.5</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 动态数据源 --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>2.5.4</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency></dependencies

配置文件yml

spring:elasticsearch:rest:uris: 192.168.254.190:9200,192.168.254.191:9200,192.168.254.192:9200datasource:druid:stat-view-servlet:# 默认true 内置监控页面首页/druid/index.htmlenabled: falseinitial-size: 20max-active: 60min-idle: 20max-wait: 30000dynamic:primary: masterstrict: falsedatasource:master: ***driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: ***url: jdc:url: ***driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriverusername: sapassword: ***

数据库实体

@Data
@EqualsAndHashCode()
@TableName("carPosition")
public class CarPosition {@TableId(value = "id")private Long id;@TableField("vehicleIdentificationNumber")private String vehicleIdentificationNumber;@TableField("collectionTime")private LocalDateTime collectionTime;/*** 经度*/private String longitude;/*** 纬度*/private String latitude;}

es实体

@Data
@FieldNameConstants
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "#{@dynamicIndex.getIndex()}", createIndex = false)
public class ObdModel implements Serializable {@Idprivate Long id;@Field(type = FieldType.Text)private String name;@GeoPointFieldprivate GeoPoint location;@Field(type = FieldType.Date, format = DateFormat.custom, pattern ="yyyy-MM-dd HH:mm:ss:SSS")private LocalDateTime datadate;
}

将数据库数据存储到es


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;import com.sunfeng.elasticsearch.entity.CarPosition;
import com.sunfeng.elasticsearch.es.model.ObdModel;
import com.sunfeng.elasticsearch.es.repository.ObdModelRepository;
import com.sunfeng.elasticsearch.es.utils.DynamicIndex;
import com.sunfeng.elasticsearch.service.CarPositionService;import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.geo.GeoPoint;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;import javax.annotation.Resource;import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;import static com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil.yyyy_MM_dd_HH_mm_ss;@Slf4j
@SpringBootTest
class ElasticsearchSpringdataApplicationTests {@Resourceprivate ObdModelRepository obdModelRepository;@Resourceprivate DynamicIndex dynamicIndex;@Resourceprivate ElasticsearchRestTemplate restTemplate;@Resourceprivate CarPositionService carPositionService;@Testpublic void createIndex() {//生成索引名称String obdIndex = "obd2";Document mapping = restTemplate.indexOps(IndexCoordinates.of(obdIndex)).createMapping(ObdModel.class);//判断索引库中是否存在该索引if (!restTemplate.indexOps(IndexCoordinates.of(obdIndex)).exists()) {restTemplate.indexOps(IndexCoordinates.of(obdIndex)).create();//创建映射restTemplate.indexOps(IndexCoordinates.of(obdIndex)).putMapping(mapping);}}@Testpublic void contextLoads() {dynamicIndex.setIndex("obd");Iterable<ObdModel> all = obdModelRepository.findAll();all.forEach(System.out::println);dynamicIndex.setIndex("");}//纬度正则private static String latReg = "^[\\-\\+]?((0|([1-8]\\d?))(\\.\\d{1,6})?|90(\\.0{1,6})?)$";//经度正则private static String lonReg = "^[\\-\\+]?(0(\\.\\d{1,6})?|([1-9](\\d)?)(\\.\\d{1,6})?|1[0-7]\\d{1}(\\.\\d{1,6})?|180(\\.0{1,6})?)$";public static void main(String[] args) {System.out.println(LocalDateTime.parse("2023-08-04 19:00:00", yyyy_MM_dd_HH_mm_ss).toInstant(ZoneOffset.of("+8")).toEpochMilli());}@Testpublic void dbToEs() {log.info("开始统计!!");LambdaQueryWrapper<CarPosition> lambdaQueryWrapper = new LambdaQueryWrapper<CarPosition>();dynamicIndex.setIndex("obd202308");List<CarPosition> carPositionList = carPositionService.list(lambdaQueryWrapper);/*** 获取分页数据*/log.info("需要处理的数据量为:{}", carPositionList.size());carPositionList = carPositionList.parallelStream().filter(carPosition -> ObjectUtil.isNotEmpty(carPosition.getLatitude()) &&ObjectUtil.isNotEmpty(carPosition.getLongitude()) &&ReUtil.isMatch(latReg, carPosition.getLatitude()) &&ReUtil.isMatch(lonReg, carPosition.getLongitude())).collect(Collectors.toList());log.info("排除部分脏数据后为:{}", carPositionList.size());ArrayList<ObdModel> obdModels = new ArrayList<>();//批量保存提高效率for (int i = 0; i < carPositionList.size(); i++) {CarPosition carPosition = carPositionList.get(i);ObdModel obdModel = new ObdModel();obdModel.setId(carPosition.getId());obdModel.setName(carPosition.getVehicleIdentificationNumber());obdModel.setDatadate(carPosition.getCollectionTime());GeoPoint geoPoint = new GeoPoint(Double.parseDouble(carPosition.getLatitude()), Double.parseDouble(carPosition.getLongitude()));obdModel.setLocation(geoPoint);obdModels.add(obdModel);if (obdModels.size() % 10000 == 0) {log.info("开始保存");obdModelRepository.saveAll(obdModels);log.info("结束保存");obdModels.clear();}}obdModelRepository.saveAll(obdModels);}}

es数据查询

package com.sunfeng.elasticsearch;import com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;import static com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil.getDateTimeOfTimestamp;
import static com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil.yyyy_MM_dd_HH_mm_ss;@Slf4j
@SpringBootTest
public class TestSearchDocument {@Resourceprivate RestHighLevelClient restHighLevelClient;@Testpublic void contextLoads() throws IOException {//创建查询请求SearchRequest searchRequest = new SearchRequest();searchRequest.indices("obd202308");GeoPoint geoPoint = new GeoPoint(36.508270D, 117.848530D);//条件1、设置搜索半径GeoDistanceQueryBuilder distanceQueryBuilder = QueryBuilders.geoDistanceQuery("location").point(geoPoint).distance(10000, DistanceUnit.METERS).geoDistance(GeoDistance.ARC); //设置查询精度//条件3、设置搜索区间 时间区间//注意: 时间格式要用 yyyy-MM-dd HH:mm:ss:SSSRangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("datadate").gt("2023-08-04 19:00:00:000").lte("2023-08-04 20:00:00:000");// 组合查询条件BoolQueryBuilder must = QueryBuilders.boolQuery().must(rangeQueryBuilder).must(distanceQueryBuilder);//条件2:按照距离排序//构建GeoDistanceSortBuilder设置按距离排序参数GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort("location", geoPoint);//升序排序sort.order(SortOrder.ASC);//构建检索SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource().from(0).size(10000).query(must).sort(sort);// 设置SearchRequest搜索参数searchRequest.source(sourceBuilder);log.info("开始搜索");// 执行ES请求SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);log.info("结束搜索");SearchHits hits = searchResponse.getHits();log.info("检索结果数量为:{}", "" + hits.getHits().length);//结果打印hits.forEach(hit -> {Map<String, Object> sourceAsMap = hit.getSourceAsMap();// 获取坐标Object location = sourceAsMap.get("location");String datadate = sourceAsMap.get("datadate").toString();Long id = Long.valueOf(sourceAsMap.get("id").toString());//获取距离值,并保留两位小数点BigDecimal geoDis = BigDecimal.valueOf((Double) hit.getSortValues()[0]);System.out.println("获取坐标:" + location + ",时间:" + datadate + ",距离:" + geoDis + ",id:" + id);});}
}
2023-08-20 23:16:51.745  INFO 8624 --- [           main] c.s.elasticsearch.TestSearchDocument     : 开始搜索
2023-08-20 23:16:52.705  INFO 8624 --- [           main] c.s.elasticsearch.TestSearchDocument     : 结束搜索
2023-08-20 23:16:52.706  INFO 8624 --- [           main] c.s.elasticsearch.TestSearchDocument     : 检索结果数量为:1401

索引数据规模大概1124W,搜索大概只需1秒左右 还可以进一步优化
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/99026.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

赴日IT工作 平时接私活开发能去日本搞个IT公司吗?

有小伙伴问&#xff0c;我平时也会接一些私活开发项目&#xff0c;可以直接去日本搞一个IT公司吗&#xff1f;首先给出まとめ&#xff08;总结&#xff09;&#xff0c;如果你没有日本项目经验的话建议先找个会社试试&#xff0c;如果有项目经验的话&#xff0c;那你把前老板的…

PHP入门基础教程 - 专栏导读

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

人工智能引领图文扫描新趋势

1. 背景和影响 近日&#xff0c;中国大学生服务外包创新创业大赛决赛在江南大学圆满落幕。为满足现代服务产业企业的现实需求&#xff0c;本次竞赛内容设计充分聚焦企业发展中所面临的技术、管理等现实问题&#xff0c;与产业的结合度更紧密&#xff0c;智能文字识别技术是大赛…

spad芯片学习总结

一、时间相关单光子计数法TCSPC(Time correlated single photon counting) 1> 如果spad接收用单次发射、峰值检测会怎么样 首先spad是概率性触发的器件&#xff0c;探测到的概率远小于1&#xff0c;而且不仅接收信号的光子可以触发&#xff0c;环境光噪声一样会被spad接收到…

Flink 数据集成服务在小红书的降本增效实践

摘要&#xff1a;本文整理自实时引擎研发工程师袁奎&#xff0c;在 Flink Forward Asia 2022 数据集成专场的分享。本篇内容主要分为四个部分&#xff1a; 小红书实时服务降本增效背景Flink 与在离线混部实践实践过程中遇到的问题及解决方案未来展望 点击查看原文视频 & 演…

Selenium的基本使用

文章目录 引入一.选择元素的基本方法1.根据id 选择元素2.根据 class属性选择元素当元素有 多个class类型 时 3.根据 tag名 选择元素4.通过WebElement对象选择元素5.find_element 和 find_elements 的区别 二.等待界面元素出现1.隐式等待2.显示等待 三.操控元素的基本方法1.点击…

基于springboot+vue的武汉旅游网(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

mysql知识点+面试总结

目录 1 mysql介绍 2 数据库常见语法 3 数据库表的常见语法 4 其他常见语法&#xff08;日期&#xff0c;查询表字段&#xff09; 5 JDBC开发步骤 6 索引 6.1 索引常见语法 7 常见面试总结 8 java代码搭建监控页面 1 mysql介绍 数据库&#xff1a;存储在硬盘上的文件系统…

使用 Visual Studio Code Docker 工具调试 .NET 容器

作者&#xff1a;Chet Husk 排版&#xff1a;Alan Wang Visual Studio Code Docker 工具已发布1.26.0版本&#xff0c;这个版本为使用 .NET SDK 构建和调试容器映像提供了内置支持。 VS Code 中的 Docker 调试 Visual Studio Code Docker 工具使开发人员可以轻松入门容器。它…

阿里云2核4G服务器配置汇总表_轻量和ECS

阿里云2核4G服务器配置价格表&#xff0c;297元一年&#xff0c;配置为轻量应用服务器2核4G、4M带宽、60GB高效云盘&#xff0c;折合24元一个月。 目录 2核4G服务器轻量&#xff1a; 2核4G服务器ECS 关于轻量和ECS的区别&#xff1a; 2核4G服务器轻量&#xff1a; 云服务器…

Java请求Http接口-OkHttp(超详细-附带工具类)

简介&#xff1a;OkHttp是一个默认有效的HTTP客户端&#xff0c;有效地执行HTTP可以加快您的负载并节省带宽&#xff0c;如果您的服务有多个IP地址&#xff0c;如果第一次连接失败&#xff0c;OkHttp将尝试备用地址。这对于IPv4 IPv6和冗余数据中心中托管的服务是必需的。OkHt…

【使用Zookeeper当作注册中心】自己定制负载均衡常见策略

自己定制负载均衡常见策略 一、前言随机&#xff08;Random&#xff09;策略的实现轮询&#xff08;Round Robin&#xff09;策略的实现哈希&#xff08;Hash&#xff09;策略 一、前言 大伙肯定知道&#xff0c;在分布式开发中&#xff0c;目前使用较多的注册中心有以下几个&…

ldbk文件

ldbk是雷电的镜像文件 打开的话可以用雷电多开器弄一个模拟器然后点击备份与还原&#xff0c;选择对应的.ldbk文件去还原&#xff0c;注意版本&#xff0c;不行的话换一个试试。 正常备份雷电模拟器的镜像文件就是.ldbk&#xff0c;可以加个后缀改成.7z解压后可以直接得到.vm…

华为擎云“磨刀”,政企数字化转型“砍柴”

文|智能相对论 作者|李永华 毫无疑问&#xff0c;消费级硬件已进入稳态式红海竞争格局&#xff0c;惨烈厮杀的同时各厂商的市场地位又相对固定。 这意味着机会少的同时困难大。 于是&#xff0c;越来越多终端厂商将着力点之一转向商用市场。 华为就是其中之一。 2023年3月…

Python Web开发 Django 简介

今天来为大家介绍 Python 另一个 Web 开发框架 Django&#xff0c;它是一个基于 Python 定制的开源 Web 应用框架&#xff0c;最早源于一个在线新闻 Web 网站&#xff0c;后于2005年开源。Django 的功能大而全&#xff0c;它提供的一站式解决的思路&#xff0c;能让开发者不用在…

70 # 协商缓存的配置:通过修改时间

对比&#xff08;协商&#xff09;缓存 比较一下再去决定是用缓存还是重新获取数据&#xff0c;这样会减少网络请求&#xff0c;提高性能。 对比缓存的工作原理 客户端第一次请求服务器的时候&#xff0c;服务器会把数据进行缓存&#xff0c;同时会生成一个缓存标识符&#…

Spring事务和事务传播机制

1. Spring中事务的实现 编程式事务(手动写代码操作事务)声明式事务(利用注解自动开启和提交事务) 2. 编程式事务 import lombok.extern.slf4j.Slf4j; import mybatis.model.User; import mybatis.service.UserService; import org.springframework.beans.factory.annotation…

认识Redis

1. 前置操作 以下内容基于CentOS 1.1. 安装 yum -y install redis 1.2. 启动 redis-server /etc/redis.conf & 1.3. 打开 redis-cli 1.4. 停止 redis-cli shutdown 1.5. 设置远程连接 修改 /etc/redis/redis.conf 修改 bind 127.0.0.1为 bind 0.0.0.0 1.6. 使用…

docker优点简介和yum方式安装

一.docker简介 二.docker的优点 1.交付和部署速度快 2.高效虚拟化 3.迁移性和扩展性强 4.管理简单 三.docker的基本概念 1.镜像 2.容器 3.仓库 四.docker的安装部署 &#xff08;1&#xff09;点击容器 ​&#xff08;2&#xff09;选择docker-ce&#xff0c;根据相…

OAuth2.0一 Spring Security OAuth2.0

这里主讲OAuth2.0 学习OAuth2前提&#xff1a; 掌握Spring Security Spring Security学习 一 OAuth2.0介绍 OAuth&#xff08;Open Authorization&#xff09;是一个关于授权&#xff08;authorization&#xff09;的开放网络标准&#xff0c;允许用户授权第三方应用访问他们…