在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/PHP/ 公眾號(hào)有幾十萬(wàn)粉絲,如何在對(duì)接的時(shí)候快速同步到本地?cái)?shù)據(jù)庫(kù)進(jìn)行運(yùn)營(yíng)

公眾號(hào)有幾十萬(wàn)粉絲,如何在對(duì)接的時(shí)候快速同步到本地?cái)?shù)據(jù)庫(kù)進(jìn)行運(yùn)營(yíng)

我使用EasyWechat嘗試開(kāi)發(fā)了一個(gè)第三方平臺(tái),然后會(huì)幫助本地商戶或公眾號(hào)運(yùn)營(yíng)一些活動(dòng),如何在公眾號(hào)授權(quán)對(duì)接后快速的將公眾號(hào)粉絲數(shù)據(jù)同步到本地?cái)?shù)據(jù)庫(kù)方便運(yùn)營(yíng)?我先前的想法是用戶有交互的時(shí)候再觸發(fā)同步,目前是使用的手動(dòng)方式和命令行方式,手動(dòng)方式如下:

/**
     * 同步
     */
    public function sync()
    {
        $account = $this->request->param('account', 0, 'intval');
        $account = AccountService::getDataById($account);
        if (empty($account)) {
            $this->error('參數(shù)錯(cuò)誤');
        }
        //頁(yè)碼
        $page = $this->request->param('page', 0, 'intval');
        $page_size = 50;
        //微信實(shí)例
        $wechat = WechatService::applicationInit($account);
        
        //先從緩存中讀取
        $fans = cache('wechat_fans_'.$account->id);
        if (!$fans) {
            echo '從騰訊拉取';
            //從騰訊拉取第一頁(yè)
            $datas = $wechat->user->lists();
            $total = ceil($datas['total'] / $datas['count']);
            $fans = $datas['data']['openid'];
            for ($i = 1; $i < $total; $i++) {
                $datas = $wechat->user->lists($datas['next_openid']);
                $lists = $datas['data']['openid'];
                foreach ($lists as $k => $v) {
                    array_push($fans, $v);
                }
            }
            //設(shè)置緩存
            cache('wechat_fans_'.$account->id, $fans);
        }
        foreach ($fans as $k => $v) {
            if ($k <= $page * $page_size) {
                continue;
            }
            if ($k > ($page + 1) * $page_size) {
                return $this->success('更新下一頁(yè)', url($this->request->controller().'/sync', ['account' => $account->id, 'page' => $page + 1]));
            }
            echo '同步'.$k.'成功<br/>';
            try {
                UserService::syncDataByServer($account, $v);
            } catch (\Exception $e) {
                echo '同步'.$k.'出錯(cuò)<br/>';
                continue;
            }
        }
        //刪除緩存
        cache('wechat_fans_'.$account->id, null);
        return $this->success('同步完成', url($this->request->controller().'/index', ['account' => $account->id]));
    }

這種使用分頁(yè)同步在瀏覽器執(zhí)行的方式速度非常慢,大約幾萬(wàn)粉絲都要跑很久,然后跟這個(gè)類(lèi)似的我寫(xiě)了一個(gè)命令行方式,執(zhí)行也很慢。

<php
namespace app\wechat\command;
use app\wechat\service\AccountService;
use app\wechat\service\WechatService;
use app\wechat\service\UserService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Option;

/**
 * 同步用戶命令
 * Class SyncUser
 * @package app\wechat\command
 */
class SyncUser extends Command
{
    /**
     * 命令行配置
     */
    protected function configure()
    {
        //設(shè)置命令名稱(chēng)及描述
        $this->setName('Wechat:SyncUser')
            ->addOption('account', 0, Option::VALUE_REQUIRED, '賬號(hào)ID.')
            ->setDescription('同步公眾號(hào)用戶');
    }

    /**
     * 命令
     * @return int|null|void
     */
    protected function execute(Input $input, Output $output)
    {
        ini_set('memory_limit', '1024M');
        if (!$input->hasOption('account')) {
            $output->writeln("請(qǐng)輸入賬號(hào)");
            return null;
        }
        $account = $input->getOption('account');
        $account = AccountService::getDataById($account);
        if (!$account) {
            $output->writeln("參數(shù)錯(cuò)誤");
            exit;
        }
        //微信實(shí)例
        $wechat = WechatService::applicationInit($account);
        //先從緩存中讀取
        $fans = cache('wechat_fans_'.$account->id);
        if (!$fans) {
            $output->writeln("從騰訊拉取粉絲");
            //從騰訊拉取第一頁(yè)
            $datas = $wechat->user->lists();
            $total = ceil($datas['total'] / $datas['count']);
            $fans = $datas['data']['openid'];
            for ($i = 1; $i < $total; $i++) {
                $datas = $wechat->user->lists($datas['next_openid']);
                $lists = $datas['data']['openid'];
                foreach ($lists as $k => $v) {
                    array_push($fans, $v);
                }
            }
            //設(shè)置緩存
            cache('wechat_fans_'.$account->id, $fans);
        }
        foreach ($fans as $k => $v) {
            try {
                UserService::syncDataByServer($account, $v);
            } catch (\Exception $e) {
                $output->writeln("同步{$k}出錯(cuò)");
                continue;
            }
        }
        //刪除緩存
        cache('wechat_fans_'.$account->id, null);
        $output->writeln("同步完成");
    }
}

求教各位大神有沒(méi)有比較好的方案。麻煩詳細(xì)些,本人不是專(zhuān)業(yè)的程序員,太簡(jiǎn)略了看不懂。謝謝!

回答
編輯回答
傲嬌范

你是想把公眾號(hào)的粉絲拉到你本地?cái)?shù)據(jù)庫(kù)?如果單個(gè)進(jìn)城拉取慢,可以開(kāi)啟多個(gè)進(jìn)程跑

2017年4月22日 19:53
編輯回答
未命名

在用戶進(jìn)行授權(quán)接入后,進(jìn)行粉絲數(shù)據(jù)同步主要有兩個(gè)部分,一個(gè)歷史粉絲數(shù)據(jù)同步,這個(gè)利用后臺(tái)程序在公眾號(hào)授權(quán)后就可以開(kāi)始同步了,獲取用戶列表接口一次也只能獲取一萬(wàn)個(gè)openid,一個(gè)公眾號(hào)一個(gè)線程也就夠了, 沒(méi)有必要立即跑完,本身微信公眾號(hào)接口就有頻率限制,如果你覺(jué)得速度實(shí)在是慢,也可以開(kāi)幾個(gè)進(jìn)程來(lái)處理。 幾萬(wàn)個(gè)粉絲的公眾號(hào)其實(shí)很快就能跑完了,放在后臺(tái)任務(wù)執(zhí)行也不用人工執(zhí)行。
二是新的粉絲數(shù)據(jù),在關(guān)注和取消關(guān)注事件里面,你可以在事件回調(diào)中處理粉絲數(shù)據(jù),這樣就不用重新拉取所有的粉絲數(shù)據(jù)了。
其實(shí)幾萬(wàn)個(gè)粉絲數(shù)據(jù)很快就處理完了, 我跑過(guò)兩千多萬(wàn)粉絲的數(shù)據(jù),也就幾天,而且接口調(diào)用頻率放的很慢了。

2018年3月4日 23:54
編輯回答
帥到炸

是不是UserService::syncDataByServer($account, $v);這個(gè)方法慢?改成批量同步試下?而且?guī)资f(wàn)放到一個(gè)fans數(shù)組里內(nèi)存消耗很大吧。感覺(jué)可以結(jié)合微信的每1萬(wàn)條數(shù)據(jù)獲取后接著批量處理一次。

2017年5月24日 14:58