商品微服务代码
1 安装composer包
在商品微服务根目录下,执行:
[root@100 swoft_order]# composer require elasticsearch/elasticsearch
这样,我们的商品微服务就支持elasticsearch了。
2 客户端
app\client\swoft\app\Rpc\Lib\GoodsInterface.php
<?php
namespace App\Rpc\Lib;
/**
*
* Class GoodsInterface
*
* @since 2.0
**/
interface GoodsInterface {
public function getList(int $id, $type, int $count = 10): array;
public function getDetail(int $sku_id) : array;
public function addGoods(array $data): array;
public function searchEsGoods(array $data): array;
}
app\client\swoft\app\Http\Controller\
<?php declare(strict_types=1);
namespace App\Http\Controller;
use App\Rpc\Lib\GoodsInterface;
use Exception; use Swoft\Co;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Rpc\Client\Annotation\Mapping\Reference;
use Swoft\Http\Message\Request;
/**
* Class RpcController
*
* @since 2.0
*
* @Controller(prefix="/goods")
*/
class GoodsController {
/**
* @Reference(pool="goods.pool")
*
* @var GoodsInterface
*/
private $goodsService;
/**
* @RequestMapping("addGoods")
* @return array
*/
public function addGoods(Request $request): array
{
$data = $request->input();
$data = [];
$result = $this->goodsService->addGoods($data);
return [$result];
}
/**
* @RequestMapping("searchEsGoods")
* @return array
*/
public function searchEsGoods(Request $request): array
{
$data = $request->input();
$result = $this->goodsService->searchEsGoods($data);
return [$result];
}
// ...
} ?>
3. 服务端
<?php declare(strict_types=1);
namespace App\Rpc\Service;
use App\Rpc\Lib\GoodsInterface;
use Exception;
use RuntimeException;
use Swoft\Co;
use Swoft\Config\Annotation\Mapping\Config;
use Swoft\Rpc\Server\Annotation\Mapping\Service;
/**
* Class GoodsService
*
* @since 2.0
*
* @Service()
*/
class GoodsService implements GoodsInterface {
// ...
/**
* @param array $data
*
* @return array
*/
public function addGoods(array $data): array
{
/*实际场景中,大家封装到自己的配置文件中*/
$hosts = [
'192.168.169.120:9210', //IP+端口
];
$client = \Elasticsearch\ClientBuilder::create()->setHosts($hosts)->build();
/*这里写死数据,实际场景中,根据需求替换成自己的数据*/
$params = [
'index' => 'goods_list',
'id' => 123,
'body' => [
'id' => '123',
'goods_name' => '测试商品的名称',
'goods_description' => '测试商品的描述',
'goods_info' => '...',
]
];
$response = $client->index($params);
return $response;
}
/**
* @param array $data
* @return array
*/
public function searchEsGoods(array $data): array
{
/*实际场景中,大家封装到自己的配置文件中*/
$hosts = [
'192.168.169.120:9210', //IP+端口
];
$client = \Elasticsearch\ClientBuilder::create()->setHosts($hosts)->build();
/*这里写死数据,实际场景中,同学们根据需求替换成自己的数据*/
$params = [
'index' => 'goods_list',
'body' => [
'query' => [
'match' => [
'goods_name' => '测试'
]
]
]
];
$response = $client->search($params);
print_r($response);
return $response;
}
}
?>
4.存在问题
注意:有一些版本的swoole可能会存在问题;这是因为swoole底层的一键协程化导致的
因为底层在运行 curl_init 函数的时候会自动拦截并切换为 swoole\curl\handler 对象因对方式修改框架底层: app\server\swoft\vendor\swoft\server\src\Server.php 注释如下代码
Runtime::enableCoroutine();
5.利用Go实现MySQL binlog与 es数据同步
5.1 安装go
go官网:https://golang.google.cn/dl/
注意!安装 注意!安装go的同时也需要安装 的同时也需要安装git
wget https://golang.google.cn/dl/go1.15.2.linux-amd64.tar.gz tar -C /usr/local -zxvf go1.15.2.linux-amd64.tar.gz
配置环境变量 vi /etc/profile
export GOROOT=/usr/local/go
export GOPATH=/www/wwwroot/2007_SRM/app/go
export PATH=$PATH:/usr/local/go/bin
其中GOPATH为go的项目目录地址,对应目录内容
5.2 修改MySQL binlog日志模式
需要值得注意的是,go-mysql-elasticsearch 支持binlog的日志模式为row模式因此建议在配置MySQLbinlog的时候需指定该模式
log-bin=mysql-bin
binlog_format=row
5.3 go-mysql-elasticsearch安装
go env -w GOPROXY=https://goproxy.cn
go get github.com/siddontang/go-mysql-elasticsearch
cd $GOPATH/src/github.com/siddontang/go-mysql-elasticsearch
make
如下为配置 river.toml
# MySQL 配置:地址,用户名,密码
my_addr = "192.168.169.***:3306"
my_user = "root"
my_pass = "0000"
# Elasticsearch地址
es_addr = "192.168.169.120:9212"
# 存储数据的位置
data_dir = "/var"
# Inner Http status address
stat_addr = "192.168.169.120:12800"
stat_path = "/es"
# pseudo server id like a slave
server_id = 1001
# mysql or mariadb
flavor = "mysql"
# mysqldump execution path
# mysqldump = "mysqldump"
# minimal items to be inserted in one bulk
bulk_size = 128
# force flush the pending requests if we don't have enough items >= bulk_size
flush_bulk_time = "200ms"
# Ignore table without primary key
skip_no_pk_table = false
# elasticsearch 与 mysql 同步时对应的数据库名称
# mysql的数据源
[[source]]
schema = "srm"
tables = ["goods"]
# es 映射的mapping
[[rule]]
schema = "srm"
table = "goods"
# es的索引名
index = "srm_goods"
type = "link_info"
启动
$GOPATH/src/github.com/siddontang/go-mysql-elasticsearch/bin/go-mysql-elasticsearch -config=/xxx/river.toml