套「多商戶系統(tǒng)對接阿里云圖像搜索(Image Search)做以圖找商品」的落地方案(架構(gòu)、數(shù)據(jù)設(shè)計、對接流程、Java 代碼示例、風(fēng)控與成本要點(diǎn))。我直接按能開干的粒度寫,照著做就行。
1. 選型與整體思路
- 能力:阿里云 Image Search 支持以圖搜圖,提供“入庫/搜索/刪除/更新”等 API 與官方 SDK(Java/Node 等)。推薦使用 2019-03-25 版本的 OpenAPI / V3 SDK。(阿里云)
- 關(guān)鍵接口:AddImage(入庫)、SearchImage(搜索),以及對應(yīng)的 SDK 方法(例如 Java V3:Add、SearchImageByPic 等命名)。(阿里云, 阿里云, 阿里云幫助中心)
- 接入方式:HTTP 公網(wǎng)或 VPC 端點(diǎn),按 OpenAPI 規(guī)范簽名/鑒權(quán);生產(chǎn)建議走 VPC + 專線/云企業(yè)網(wǎng)。(阿里云)
- 性能配額:入庫默認(rèn) QPS 有限(實例規(guī)格 10 萬容量默認(rèn) 1 QPS,其它規(guī)格默認(rèn) 5 QPS),需要用異步隊列與批處理。(阿里云)
2. 多商戶架構(gòu)(參考)
組件:
- OSS:商品主圖、細(xì)節(jié)圖原圖存儲。
- Image Search 實例:向量索引;入庫/搜索都打到它。
- Ingestion Service(異步入庫):消費(fèi)隊列,把每個商戶商品圖入庫到 Image Search。
- Search API 網(wǎng)關(guān):對前端/小程序/商家后臺暴露統(tǒng)一“以圖找貨”接口。
- RDS/Redis:SKU 與圖片索引映射、緩存熱數(shù)據(jù)。
- MQ:如 RocketMQ/RabbitMQ,用于入庫削峰。
商戶隔離策略(3 選 1,可疊加):
- 屬性過濾:入庫時把 merchant_id 寫入自定義屬性(如 str_attr),搜索時帶過濾條件,僅返回該商戶結(jié)果。(阿里云文檔)
- PicName/外部ID 命名規(guī)范:picName = {merchantId}-{skuId}-{imageNo},搜索命中后用 picName 反查 SKU。(阿里云)
- 分實例:大客單獨(dú)買一個 Image Search 實例,小商戶共享實例,通過屬性過濾做軟隔離。(阿里云)
3. 數(shù)據(jù)模型(簡化)
- merchant(id, name, ... )
- product(id, merchant_id, sku, title, ... )
- product_image(id, product_id, url, status, md5, ... )
- imagesearch_index(id, merchant_id, sku, pic_name, int_attr, str_attr, status, last_sync_at)
- search_log(id, merchant_id, query_img_md5, topk, latency_ms, result_sku_json, created_at)
4. 流程
入庫(商品上新/更新)
- 商戶上傳商品圖 → 存 OSS,生成標(biāo)準(zhǔn) 800px 邊長壓縮圖與 MD5。
- 發(fā)送 MQ 消息(merchantId/sku/picURL 等)。
- Ingestion Service 拉取消息: 組織 picName 與屬性:str_attr = merchantId,必要時 int_attr 放品類/可篩選字段。 調(diào) AddImage(或 SDK 的 Add)。 回寫 imagesearch_index 狀態(tài)。(阿里云, 阿里云幫助中心)
搜索(C 端或商家端)
- 前端上傳拍照圖(或粘貼圖 URL)。
- Search API: 先做安全/大小校驗,必要時壓縮到 ≤ 2MB、短邊 ≥ 300px。 調(diào) SearchImage/SearchImageByPic,帶 filter = str_attr=merchantId AND ...。 拿到命中列表(含 picName/score),解析出 sku,回庫查價存貨,組裝結(jié)果返回。(阿里云, 阿里云文檔)
5. Java 對接示例(V3 SDK 思路)
說明:阿里云會同時提供 OpenAPI 與多語言 SDK。以下示例基于官方文檔給出的 Java V3 用法思路(命名可能因版本略有差異,實際以你引入的 SDK 文檔示例為準(zhǔn))。(阿里云, 阿里云幫助中心, GitHub)
// 依賴(示意):com.aliyun:alibabacloud-imagesearch20200320 或最新 V3 SDK
// 初始化客戶端
ImageSearchClient buildClient(String accessKeyId, String accessKeySecret, String region) {
Config config = new Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret)
.setRegionId(region); // 如 cn-shanghai
return new ImageSearchClient(config);
}
// 入庫:Add(等價于 AddImage)
void addImage(ImageSearchClient client, String instanceName, String picName, String picUrl,
String merchantId, Integer catId) throws Exception {
AddRequest req = new AddRequest()
.setInstanceName(instanceName)
.setPicName(picName)
.setPicUrl(picUrl)
.setCategoryId(catId) // 可選:商品類目
.setStrAttr(merchantId); // 關(guān)鍵:商戶隔離
AddResponse resp = client.add(req);
// 檢查 resp.getBody().getSuccess() / code 等,寫入庫狀態(tài)
}
// 搜索:SearchImageByPic
List searchByPic(ImageSearchClient client, String instanceName, byte[] imageBytes,
String merchantId, Integer topK) throws Exception {
SearchImageByPicRequest req = new SearchImageByPicRequest()
.setInstanceName(instanceName)
.setPicContent(Base64.getEncoder().encodeToString(imageBytes))
.setFilter("str_attr='" + merchantId + "'")
.setNum(topK);
SearchImageByPicResponse resp = client.searchImageByPic(req);
// 解析 resp:拿到 items 列表(包含 picName/score),再映射 SKU
return resp.getBody().getAuctions(); // 命名以你引入的 SDK 為準(zhǔn)
}
6. 工程細(xì)節(jié)
- 分庫/分表/分緩存:merchant_id 作為所有商品與圖片索引表的前綴鍵;Redis 用 imagesearch:{merchantId}:{sku}。
- 索引一致性:商品下架/圖片替換要同步 DeleteImage 或 Update;入庫失敗重試+死信隊列。