• ElasticSearch2:集群安装


    0、Linux系统参数设置

    Linux进程数系统限制查看

    [root@ip101 config]# sysctl kernel.pid_max
    kernel.pid_max = 131072
    [root@ip101 config]# 
    

    修改这个值的方法

    在/etc/sysctl.conf中添加kernel.pid_max = 65535
    # vim /etc/sysctl.conf
    kernel.pid_max = 65535
    

    1、ELK

    Elasticsearch:用于存储收集到的日志信息;
    Logstash:用于收集日志,SpringBoot应用整合了Logstash以后会把日志发送给Logstash,Logstash再把日志转发给Elasticsearch;
    Kibana:通过Web端的可视化界面来查看日志。

    2、安装

    2.1 ElasticSearch

    1)下载
    2)解压安装
    3)创建一个es启动用户,因为不能用root来启动,这里就建一个叫'elastic'的用户
    4) 改变elasticsearch文件夹所有者到创建的elsatic用户

     chown -R elastic:elastic elasticsearch-7.4.1/
    

    5)用root用户,编辑limits.conf配置文件,修改用户最大可创建文件数,因为可创文件数太小的话es启动不了

    vim /etc/security/limits.conf
    
     #添加以下配置
     elastic   hard    nofile  65536
     elastic   soft    nofile  65536
     *       soft    nproc   65536
     *       hard    nproc   65536
    

    6)用root用户,修改配置文件sysctl.conf文件,调大最大虚拟内存,因为虚拟内存太小的话es也启动不了

     vim /etc/sysctl.conf
     
     #添加
     vm.max_map_count=655360
    #因为默认vm.max_map_count=65530,因此缺省配置下,单个jvm能开启的最大线程数为其一半,即3w左右,大概32k的量
    
     #添加完成后必须执行以下命令配置才可生效
     #sysctl -p
    
    1. 然后进入es文件夹,修改config/elasticsearch.yml配置文件
    network.host: 0.0.0.0
    
    1. 切换到elastic用户下就可以启动了( es7要使用jdk11)
    su elastic
    
    #进到es的bin目录下
    cd elasticsearch-7.4.1/bin
    ./elsticsearch
    #即可启动。
    
    #要想放到后台进程启动,就用
    ./elsticsearch -d
    

    9)访问 http://192.168.8.101:9200

    {
      "name" : "ip101",
      "cluster_name" : "elasticsearch",
      "cluster_uuid" : "_na_",
      "version" : {
        "number" : "7.4.1",
        "build_flavor" : "default",
        "build_type" : "tar",
        "build_hash" : "fc0eeb6e2c25915d63d871d344e3d0b45ea0ea1e",
        "build_date" : "2019-10-22T17:16:35.176724Z",
        "build_snapshot" : false,
        "lucene_version" : "8.2.0",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
      },
      "tagline" : "You Know, for Search"
    }
    

    10)集群方式安装

    cluster.name: escluster
    
    node.name: ip101      #node.name: node-2#node.name: node-3
    node.master: true
    node.data: true
    
    network.host: 0.0.0.0
    http.port: 9200
    transport.tcp.port: 9300
    
    #Elasticsearch7新增参数,写入候选主节点的设备地址,来开启服务时就可以被选为主节点,由discovery.zen.ping.unicast.hosts:参数改变而来
    discovery.seed_hosts: ["ip101","ip102","ip103"]	
    #Elasticsearch7新增参数,写入候选主节点的设备地址,来开启服务时就可以被选为主节点
    cluster.initial_master_nodes: ["ip101"]
    #ES7后参数被废弃
    #discovery.zen.ping.unicast.hosts: ["192.168.8.101:9300", "192.168.8.102:9300", "192.168.8.103:9300"]
    
    
    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    11) 启动

    首先启动master, ip101
    bin/elasticsearch
    [2019-11-11T20:07:49,701][INFO ][o.e.p.PluginsService     ] [ip101] no plugins loaded
    [2019-11-11T20:07:58,140][INFO ][o.e.x.s.a.s.FileRolesStore] [ip101] parsed [0] roles from file [/opt/app/elasticsearch-7.4.1/config/roles.yml]
    [2019-11-11T20:08:00,499][INFO ][o.e.x.m.p.l.CppLogMessageHandler] [ip101] [controller/1292] [Main.cc@110] controller (64 bit): Version 7.4.1 (Build 973380bdacc5e8) Copyright (c) 2019 Elasticsearch BV
    [2019-11-11T20:08:01,717][DEBUG][o.e.a.ActionModule       ] [ip101] Using REST wrapper from plugin org.elasticsearch.xpack.security.Security
    [2019-11-11T20:08:02,981][INFO ][o.e.d.DiscoveryModule    ] [ip101] using discovery type [zen] and seed hosts providers [settings]
    [2019-11-11T20:08:05,568][INFO ][o.e.n.Node               ] [ip101] initialized
    [2019-11-11T20:08:05,569][INFO ][o.e.n.Node               ] [ip101] starting ...
    [2019-11-11T20:08:05,899][INFO ][o.e.t.TransportService   ] [ip101] publish_address {192.168.8.101:9300}, bound_addresses {[::]:9300}
    [2019-11-11T20:08:05,911][INFO ][o.e.b.BootstrapChecks    ] [ip101] bound or publishing to a non-loopback address, enforcing bootstrap checks
    [2019-11-11T20:08:05,963][INFO ][o.e.c.c.Coordinator      ] [ip101] cluster UUID [frwwuxfNSGaQbSpZ4IUZsw]
    [2019-11-11T20:08:15,990][WARN ][o.e.c.c.ClusterFormationFailureHelper] [ip101] master not discovered or elected yet, an election requires at least 2 nodes with ids from [RSC4lA2WRkStPdLtbjATYA, G6JuifsbRh2gQ18Ze5avTg, Kln4qU2iTG-fFzod-eSzzw], have discovered [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] which is not a quorum; discovery will continue using [192.168.8.102:9300, 192.168.8.103:9300] from hosts providers and [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] from last-known cluster state; node term 6, last-accepted version 36 in term 6
    [2019-11-11T20:08:25,992][WARN ][o.e.c.c.ClusterFormationFailureHelper] [ip101] master not discovered or elected yet, an election requires at least 2 nodes with ids from [RSC4lA2WRkStPdLtbjATYA, G6JuifsbRh2gQ18Ze5avTg, Kln4qU2iTG-fFzod-eSzzw], have discovered [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] which is not a quorum; discovery will continue using [192.168.8.102:9300, 192.168.8.103:9300] from hosts providers and [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] from last-known cluster state; node term 6, last-accepted version 36 in term 6
    [2019-11-11T20:08:35,995][WARN ][o.e.c.c.ClusterFormationFailureHelper] [ip101] master not discovered or elected yet, an election requires at least 2 nodes with ids from [RSC4lA2WRkStPdLtbjATYA, G6JuifsbRh2gQ18Ze5avTg, Kln4qU2iTG-fFzod-eSzzw], have discovered [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] which is not a quorum; discovery will continue using [192.168.8.102:9300, 192.168.8.103:9300] from hosts providers and [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] from last-known cluster state; node term 6, last-accepted version 36 in term 6
    [2019-11-11T20:08:36,006][WARN ][o.e.n.Node               ] [ip101] timed out while waiting for initial discovery state - timeout: 30s
    [2019-11-11T20:08:36,141][INFO ][o.e.h.AbstractHttpServerTransport] [ip101] publish_address {192.168.8.101:9200}, bound_addresses {[::]:9200}
    [2019-11-11T20:08:36,142][INFO ][o.e.n.Node               ] [ip101] started
    -----------------------------------------------------------------------
    [2019-11-11T20:08:46,000][WARN ][o.e.c.c.ClusterFormationFailureHelper] [ip101] master not discovered or elected yet, an election requires at least 2 nodes with ids from [RSC4lA2WRkStPdLtbjATYA, G6JuifsbRh2gQ18Ze5avTg, Kln4qU2iTG-fFzod-eSzzw], have discovered [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] which is not a quorum; discovery will continue using [192.168.8.102:9300, 192.168.8.103:9300] from hosts providers and [{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}] from last-known cluster state; node term 6, last-accepted version 36 in term 6
    
    启动slave ip102
    [2019-11-11T20:14:57,591][INFO ][o.e.x.s.a.s.FileRolesStore] [ip102] parsed [0] roles from file [/opt/app/elasticsearch-7.4.1/config/roles.yml]
    [2019-11-11T20:15:00,189][INFO ][o.e.x.m.p.l.CppLogMessageHandler] [ip102] [controller/1175] [Main.cc@110] controller (64 bit): Version 7.4.1 (Build 973380bdacc5e8) Copyright (c) 2019 Elasticsearch BV
    [2019-11-11T20:15:01,339][DEBUG][o.e.a.ActionModule       ] [ip102] Using REST wrapper from plugin org.elasticsearch.xpack.security.Security
    [2019-11-11T20:15:02,425][INFO ][o.e.d.DiscoveryModule    ] [ip102] using discovery type [zen] and seed hosts providers [settings]
    [2019-11-11T20:15:04,996][INFO ][o.e.n.Node               ] [ip102] initialized
    [2019-11-11T20:15:04,996][INFO ][o.e.n.Node               ] [ip102] starting ...
    [2019-11-11T20:15:05,651][INFO ][o.e.t.TransportService   ] [ip102] publish_address {192.168.8.102:9300}, bound_addresses {[::]:9300}
    [2019-11-11T20:15:05,672][INFO ][o.e.b.BootstrapChecks    ] [ip102] bound or publishing to a non-loopback address, enforcing bootstrap checks
    [2019-11-11T20:15:05,731][INFO ][o.e.c.c.Coordinator      ] [ip102] cluster UUID [frwwuxfNSGaQbSpZ4IUZsw]
    [2019-11-11T20:15:06,693][INFO ][o.e.c.s.MasterService    ] [ip102] elected-as-master ([2] nodes joined)[{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true} elect leader, {ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20} elect leader, _BECOME_MASTER_TASK_, _FINISH_ELECTION_], term: 8, version: 39, reason: master node changed {previous [], current [{ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}]}, added {{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},}
    [2019-11-11T20:15:07,123][INFO ][o.e.c.s.ClusterApplierService] [ip102] master node changed {previous [], current [{ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, xpack.installed=true, ml.max_open_jobs=20}]}, added {{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},}, term: 8, version: 39, reason: Publication{term=8, version=39}
    [2019-11-11T20:15:07,492][INFO ][o.e.h.AbstractHttpServerTransport] [ip102] publish_address {192.168.8.102:9200}, bound_addresses {[::]:9200}
    [2019-11-11T20:15:07,493][INFO ][o.e.n.Node               ] [ip102] started
    
    
    [2019-11-11T20:15:08,711][INFO ][o.e.l.LicenseService     ] [ip102] license [7525ecff-bebe-420a-ae36-104709572fc2] mode [basic] - valid
    [2019-11-11T20:15:08,712][INFO ][o.e.x.s.s.SecurityStatusChangeListener] [ip102] Active license is now [BASIC]; Security is disabled
    [2019-11-11T20:15:08,775][INFO ][o.e.g.GatewayService     ] [ip102] recovered [0] indices into cluster_state
    
    master 提示信息
    
    [2019-11-11T20:15:08,540][INFO ][o.e.c.s.ClusterApplierService] [ip101] master node changed {previous [], current [{ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true}]}, added {{ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},}, term: 8, version: 39, reason: ApplyCommitRequest{term=8, version=39, sourceNode={ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true}}
    [2019-11-11T20:15:09,736][INFO ][o.e.l.LicenseService     ] [ip101] license [7525ecff-bebe-420a-ae36-104709572fc2] mode [basic] - valid
    [2019-11-11T20:15:09,737][INFO ][o.e.x.s.s.SecurityStatusChangeListener] [ip101] Active license is now [BASIC]; Security is disabled
    [2019-11-11T20:15:10,424][INFO ][o.e.x.s.a.TokenService   ] [ip101] refresh keys
    [2019-11-11T20:15:10,579][INFO ][o.e.x.s.a.TokenService   ] [ip101] refreshed keys
    
    另一台slave ip103
    [2019-11-11T20:16:57,417][INFO ][o.e.x.s.a.s.FileRolesStore] [ip103] parsed [0] roles from file [/opt/app/elasticsearch-7.4.1/config/roles.yml]
    [2019-11-11T20:16:59,953][INFO ][o.e.x.m.p.l.CppLogMessageHandler] [ip103] [controller/1175] [Main.cc@110] controller (64 bit): Version 7.4.1 (Build 973380bdacc5e8) Copyright (c) 2019 Elasticsearch BV
    [2019-11-11T20:17:01,828][DEBUG][o.e.a.ActionModule       ] [ip103] Using REST wrapper from plugin org.elasticsearch.xpack.security.Security
    [2019-11-11T20:17:02,785][INFO ][o.e.d.DiscoveryModule    ] [ip103] using discovery type [zen] and seed hosts providers [settings]
    [2019-11-11T20:17:04,856][INFO ][o.e.n.Node               ] [ip103] initialized
    [2019-11-11T20:17:04,857][INFO ][o.e.n.Node               ] [ip103] starting ...
    [2019-11-11T20:17:05,175][INFO ][o.e.t.TransportService   ] [ip103] publish_address {192.168.8.103:9300}, bound_addresses {[::]:9300}
    [2019-11-11T20:17:05,195][INFO ][o.e.b.BootstrapChecks    ] [ip103] bound or publishing to a non-loopback address, enforcing bootstrap checks
    [2019-11-11T20:17:05,237][INFO ][o.e.c.c.Coordinator      ] [ip103] cluster UUID [frwwuxfNSGaQbSpZ4IUZsw]
    [2019-11-11T20:17:06,115][INFO ][o.e.c.s.ClusterApplierService] [ip103] master node changed {previous [], current [{ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true}]}, added {{ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},{ip101}{G6JuifsbRh2gQ18Ze5avTg}{KBNr4n9mSby7fU4B1szatg}{192.168.8.101}{192.168.8.101:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},}, term: 8, version: 42, reason: ApplyCommitRequest{term=8, version=42, sourceNode={ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true}}
    [2019-11-11T20:17:06,863][INFO ][o.e.x.s.a.TokenService   ] [ip103] refresh keys
    [2019-11-11T20:17:07,373][INFO ][o.e.x.s.a.TokenService   ] [ip103] refreshed keys
    [2019-11-11T20:17:07,521][INFO ][o.e.l.LicenseService     ] [ip103] license [7525ecff-bebe-420a-ae36-104709572fc2] mode [basic] - valid
    [2019-11-11T20:17:07,522][INFO ][o.e.x.s.s.SecurityStatusChangeListener] [ip103] Active license is now [BASIC]; Security is disabled
    [2019-11-11T20:17:07,751][INFO ][o.e.h.AbstractHttpServerTransport] [ip103] publish_address {192.168.8.103:9200}, bound_addresses {[::]:9200}
    [2019-11-11T20:17:07,752][INFO ][o.e.n.Node               ] [ip103] started
    ip101提示:
    [2019-11-11T20:17:07,474][INFO ][o.e.c.s.ClusterApplierService] [ip101] added {{ip103}{Kln4qU2iTG-fFzod-eSzzw}{n51k5DKaT7GRbeY7ZY7W5g}{192.168.8.103}{192.168.8.103:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},}, term: 8, version: 42, reason: ApplyCommitRequest{term=8, version=42, sourceNode={ip102}{RSC4lA2WRkStPdLtbjATYA}{Z8N1mjdcRk6k_uLUnpWo9Q}{192.168.8.102}{192.168.8.102:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true}}
    
    ip102提示:
    [2019-11-11T20:17:05,913][INFO ][o.e.c.s.MasterService    ] [ip102] node-join[{ip103}{Kln4qU2iTG-fFzod-eSzzw}{n51k5DKaT7GRbeY7ZY7W5g}{192.168.8.103}{192.168.8.103:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true} join existing leader], term: 8, version: 42, reason: added {{ip103}{Kln4qU2iTG-fFzod-eSzzw}{n51k5DKaT7GRbeY7ZY7W5g}{192.168.8.103}{192.168.8.103:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},}
    [2019-11-11T20:17:07,629][INFO ][o.e.c.s.ClusterApplierService] [ip102] added {{ip103}{Kln4qU2iTG-fFzod-eSzzw}{n51k5DKaT7GRbeY7ZY7W5g}{192.168.8.103}{192.168.8.103:9300}{dilm}{ml.machine_memory=1023688704, ml.max_open_jobs=20, xpack.installed=true},}, term: 8, version: 42, reason: Publication{term=8, version=42}
    

    更改完成后:

    报错1

    ERROR: [3] bootstrap checks failed
    [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
    [2]: max number of threads [3818] for user [elastic] is too low, increase to at least [4096]
    [3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
    

    报错2

    ERROR: [1] bootstrap checks failed
    [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
    

    ES配置参数设置





    ES集群概念

    集群

    一个集群cluster由一个或者多个节点组成,具有相同的cluster.name,协同工作,分项数据和负载。
    当有新的节点加入或者删除了一个节点时,集群回感知到并能够平衡数据。
    ElasticSearch中可以监控很多信息,有一个最重要的就是集群健康。
    集群健康有三个状态:green(所有主要分片和复制分片都可用),yellow(所有主要分片可用,但不是所有复制分片都可用),red(不是所有的主要分片都可用)。

    节点

    一个节点node就是一个ElasticSearch的实例。
    集群中的一个节点会被选举为主节点master,它将临时管理集群级别的一些变更,譬如新建或者删除索引、增加或者移除节点等等。
    主节点不参与文档级别的变更或者搜索,所以不会成为集群的瓶颈。
    任何节点都可以成为主节点。
    用户能够与集群中的任何节点通信,包括主节点。
    每一个节点都知道文档存在于哪个节点上,可以转发请求到相应的节点上。

    分片

    一个分片shard是一个最小级别的工作单元,es把一个完整的索引分成多个分片。
    仅保存了索引中所有数据的一部分。 分片就是一个Lucene实例,并且它本身就是一个完整的搜索引擎。
    文档存储在分片中,并且在分片中被索引,但是程序不会直接与分片通信,而是与索引通信。
    Replicas分片:代表索引副本。es可以设置多个索引的副本,副本的作用是提高了系统的容错性。
    当某个节点的分片损坏或者丢失的时候可以从副本中恢复。
    还可以提高查询搜索效率,es会自动对搜索请求进行负载均衡。

  • 相关阅读:
    2021年《jmeter高级调优项目实战》秋季班(火热报名中!)
    Jmeter分布式压力测试过程可能遇到的各种坑
    Python编程与数据结构
    Xftp 提示需要升级
    [学习笔记]LGV引理
    PyTorch模型训练特征图可视化
    测试PostGIS是否安装成功
    sift算法使用
    IDEA中Maven Projects里项目灰色解决办法
    SpringCloud从入门到进阶(一)——懂生活就懂微服务
  • 原文地址:https://www.cnblogs.com/xidianzxm/p/11765632.html
Copyright © 2020-2023  润新知