在代付等涉及转账、汇款的场合,尤其是对公业务(例如代发工资等),对代付服务平台,都涉及收款方联行号查询的需求。
所谓银行联行号就是一个地区银行的唯一识别标志。用于人民银行所组织的大额支付系统、超级网银、小额支付系统、城市商业银行银行汇票系统、全国支票影像系统等跨区域支付结算业务。
在实际生活中,一般用户不会对联行号有感知,都由代付服务提供方来根据开户行信息来查询,例如代发工资中,一般提供的都是收款方的开户行信息,而不是联行号号。
联行号查询典型应用场景:根据用户输入的开户行名称(一般要求到市级分行),从联行号表快速查询最匹配的联行号。
对批量代付这样的场景,很难保证代付文件中收款方开户行信息准确性,例如用户输入字符串未:招行万泉河支行,而联行号表中为“招商银行股份有限公司北京万泉河支行”。
因此联行表查询最核心的算法需求为:要根据一个输入字符串,从联行表快速查询到最匹配的银行联行号表。
一般以前最土的做法是通过数据库like 函数或正则表达式近似查询,稍微高级点的通过双数组前缀树(Double-Array Trie)算法来做联行号查询,但效率、扩展性都较差。
联行号查询实际涉及如下核心技术需求:查询输入语句的分词、同义词、字符串匹配度处理等问题。而这正是lucene、elasticsearch这样的搜索引擎擅长的。
大致方案:
采用elasticsearch 作为基础框架,实现同义词、字符串匹配度打分等功能。
采用elasticsearch-analysis-ik 中文分词插件
采用logstash插件logstash-mysql 将mysql数据同步到elasticsearch
软件版本:
JDK:11
elasticsearch:7.3
logstash:7.3
这里使用单机配置,生产环境建议使用至少两个节点,保证高可用性
安装文件下载目录为:/home/elsearch
1、安装jdk 11
yum -y install java-11-openjdk-devel.x86_64
vi /etc/profile
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.4.11-0.el7_6.x86_64
export PATH=$PATH:$JAVA_HOME/bin
vi /etc/sysctl.conf
vm.max_map_count=655360
并执行命令:
sysctl -p
vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
* soft nproc 4096
* hard nproc 4096
2、安装elasticsearch
在国内服务器下载elasticsearch和logstash都极其慢,可以在PC上用代理下载后传到服务器上。
2.1、安装elasticsearch
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.3.0-x86_64.rpm
rpm -ivh elasticsearch-7.3.0-x86_64.rpm
systemctl enable elasticsearch
systemctl start elasticsearch
rpm 方式安装elasticsearch,相关文件目录:
配置文件目录:/etc/elasticsearch
启动命令:/usr/share/elasticsearch/bin
日志目录: /var/log/elasticsearch
2.2、修改elasticsearch配置
修改elasticsearch 绑定地址,允许远程访问,缺省只绑定127.0.0.1
vi /etc/elasticsearch/elasticsearch.yml ,修改如下内容(这里假定为单机)
network.host: 0.0.0.0
cluster.initial_master_nodes: [“node-1”]
http.cors.enabled: true
http.cors.allow-origin: /.*/
#重启elasticsearch服务
systemctl restart elasticsearch
#查看启动日志
tail -f /var/log/elasticsearch/elasticsearch.log
2.3、安装 IK 中文分词插件
/usr/share/elasticsearch/bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.3.0/elasticsearch-analysis-ik-7.3.0.zip
如果要下载插件后本地安装(如果在国内,推荐此种方式)
/usr/share/elasticsearch/bin/elasticsearch-plugin install file:///home/elasticsearch/elasticsearch-analysis-ik-7.3.0.zip
#查看分词插件analysis-ik是否安装成功
/usr/share/elasticsearch/bin/elasticsearch-plugin list|grep analysis-ik
2.4、建立同义词文件
在 asticsearch/analysis-ik下创建synonyms.txt,文件内容类似:
招商银行,招行 => 招商银行
中国建设银行,建设银行,建行 => 建设银行
中国银行,中行 => 中国银行
2.5、测试验证elasticsearch
curl -XGET ‘http://localhost:9200/?pretty‘
3、将联行表导入mysql数据库
简单起见,可以使用数据库客户端工具导入原始的联行号表。
导入调整后的表结构为:
id, bank_name,bank_code,create_date,update_date
导入sql文件参考示例代码:elasticdemo/sql/bank_code.sql
4、安装logstash
logstash用于将mysql数据库数据同步到elasticsearch中
由于只是利用logstash导入联行表数据到elasticsearch,使用频率不高,因此不安装rpm包。
4.1、下载logstash
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.3.0.tar.gz
tar zxvf logstash-7.3.0.tar.gz
cd logstash-7.3.0
以下假定logstash安装路径为:/home/elsearch/logstash-7.3.0
4.2、安装logstash-mysql
yum -y install gem
gem sources –add https://gems.ruby-china.com/ –remove https://rubygems.org/
vi Gemfile.lock
将 remote: https://rubygems.org/
修改为
remote: https://gems.ruby-china.com/
#安装logstash-input-jdbc插件
bin/logstash-plugin install logstash-input-jdbc
#查看logstash安装插件
bin/logstash-plugin list
#下载mysql jdbc driver
wget -O logstash-core/lib/jars/mysql-connector-java-8.0.17.jar https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.17/mysql-connector-java-8.0.17.jar
#编辑导入映射文件logstash-mysql.conf(searchdemo/logstash配置 有示例)
vi /home/elsearch/logstash-7.3.0/logstash-7.3.0
input {
jdbc {
jdbc_driver_library => “/home/elsearch/logstash-7.3.0/logstash-core/lib/jars/mysql-connector-java-8.0.17.jar”
jdbc_driver_class => “com.mysql.jdbc.Driver”
jdbc_connection_string => “jdbc:mysql://localhost:3306/bank?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8”
jdbc_user => “root”
jdbc_password => “root”
#schedule设置每分钟执行
schedule => “* * * * *”
statement => “SELECT * FROM bank_code WHERE bank_code.update_date >= :sql_last_value”
jdbc_paging_enabled => “true”
jdbc_page_size => “50000”
last_run_metadata_path => “/home/elsearch/logstash-7.3.0/last_run.txt”
}
}
output {
elasticsearch {
hosts => [“localhost:9200”]
index => “bank_codes”
template_name => “logstash”
template => “/home/elsearch/logstash-7.3.0/logstash.json”
template_overwrite => true
manage_template => true
}
stdout { codec => json_lines }
}
#定义Logstash模板(searchdemo/logstash配置 有示例)
vi /home/elsearch/logstash-7.3.0/logstash.json
{
“index_patterns”: [
“*”
],
“order”: 0,
“version”: 1,
“settings”: {
“number_of_shards”: 1,
“analysis”: {
“filter”: {
“my_synonym_filter”: {
“type”: “synonym”,
“synonyms_path”: “analysis-ik/synonyms.txt”
}
},
“analyzer”: {
“ik_syno”: {
“type”: “custom”,
“tokenizer”: “ik_smart”,
“filter”: [
“my_synonym_filter”
]
},
“ik_syno_max”: {
“type”: “custom”,
“tokenizer”: “ik_max_word”,
“filter”: [
“my_synonym_filter”
]
}
}
}
},
“mappings”: {
“date_detection”: true,
“numeric_detection”: true,
“dynamic_templates”: [
{
“string_fields”: {
“match”: “*”,
“match_mapping_type”: “string”,
“mapping”: {
“type”: “text”,
“norms”: false,
“analyzer”: “ik_max_word”,
“search_analyzer”: “ik_syno_max”,
“fields”: {
“keyword”: {
“type”: “keyword”
}
}
}
}
}
]
}
}
#导入mysql联行表数据到elasticsearch
/home/elsearch/logstash-7.3.0/bin/logstash -f /home/elsearch/logstash-7.3.0/logstash-mysql.conf
4.3、更新或重新导入
更新mysql数据库表后,需要重新导入,可以修改last_run_metadata_path 指定的文件的时间戳,或者修改数据库bank_code.update_date 字段时间戳
5、测试
curl -X GET ‘http://localhost:9200/_cat/indices?v‘
curl ‘localhost:9200/bank_codes/_search’ -H ‘Content-Type: application/json’ -d ‘
{
“query” : { “match” : { “bank_name” : “招行万泉河支行” }}
}’
6、开发
可以直接使用elasticsearch java high level client
转载请注明:虚拟号之家 » 使用elasticsearch实现银行联行号查询