THẢO LUẬN

Avatar
đã bình luận cho bài viết
thg 2 14, 2020 2:31 SA

Nếu là sự phụ thuộc thì tại sao presentation lại phải thông qua data rồi mới tới domain ? Thằng presenter phải thông qua domain để làm mapper tới data chứ ?

0
thg 2 14, 2020 1:54 SA

Cảm ơn tác giả vì bài viết nhé. Mong sớm nhận thêm được những bài thế này 💯

+1

Cảm ơn bạn. Rất mong được đọc phần tiếp theo.

0
thg 2 13, 2020 2:32 CH

Very Nice, Mr, Chaudhary

0
thg 2 13, 2020 2:25 CH

いいですね。ありがとうございました。😁😍😍😍 😜😜❤️❤️❤️

0
Avatar
đã bình luận cho bài viết
thg 2 13, 2020 2:21 CH

Hình 1 nói về sự phụ thuộc (dependence), hình 2 nói về workflow. Bạn đang hiểu sai.

0
thg 2 13, 2020 1:39 CH

cảm ơn ạ, thông tin rất hữu ích. 勉強になりました。

0
thg 2 13, 2020 12:40 CH

Cảm ơn bạn, thông tin hữu ích quá 🙂

0
thg 2 13, 2020 11:09 SA

Node.js phù hợp với các ứng dụng nào? Các ứng dụng có số lượng truy cập lớn, yêu cầu cập nhật theo thời gian thực

Đoạn này cũng phải xem lớn là lớn ở mức nào. Vấn đề ở chỗ nodejs xử lý bất đồng bộ các task ở các event signal, khi nó init quá nhiều event dẫn đến bị bug trong core bộ quản lý signal của Js luôn. Dù nodejs cũng có điểm mạnh/điểm yếu nhưng cái chết của nó là cost/performance chưa được tương xứng, nên các ông lớn không dùng. Ngay như facebook cũng từ bỏ nodejs mà tiếp tục PHP. và hiện tại Nodejs nó là core rồi tức là k thể nào optimize nó dc nữa còn Php này kia nó có thể làm dc điều đó thông qua caching

0
thg 2 13, 2020 8:51 SA

Hay quá bác, hiếm khi thấy bài viết dễ hiểu và chi tiết như vậy

0
thg 2 13, 2020 8:45 SA

hình như chưa có phần router anh ơi. =))))

0
thg 2 13, 2020 7:26 SA

Impliment 1 singleton chuyên đếm trên tầng app thì sao nếu không có load balance thì cũng không đến nỗi.

0

mình cũng định bổ sung việc bảo vệ ở phía người dùng mà viết xong mới nhớ ra, sẽ edit thêm sau ạ. Cảm ơn bạn đã góp ý cho mình 😍😍

+1
thg 2 13, 2020 4:25 SA

file này khá phức tạp mình up cả lên đây, bạn cần hàm nào thù lấy nhes:

<?php

namespace App\Helpers;

use App\Models\Proxy;
use Cache;
use Exception;
use GuzzleHttp\Client;
use Log;
use Symfony\Component\Process\Process;

class AwsClient
{
    const TIME_CACHE = 60; // minutes

    const CONNECT_TIME_OUT = 20; // second

    const TIME_OUT_RESPONSE = 60; // second

    /**
     * get content html from aws via proxy
     * @param $url
     * @param null $proxy
     * @return false|string|array
     */
    public static function getContent($url, $proxy = null)
    {
        $content = self::getData($url, $proxy);
        Log::debug("content type = " . gettype($content));

        if ($content && !empty($content) && is_string($content)) {
            $newContent = str_get_html($content);
            $titleraw = $newContent->find('title', 0);
            $title = $titleraw->innertext;
            Log::debug("title = $title");
            if (trim($title) != 'Amazon CAPTCHA') {
                if ($proxy && !Cache::has('proxy')) {
                    Cache::put('proxy', $proxy, self::TIME_CACHE);
                }
                self::cleanHtml($newContent);
                return $content;
            } else {
                self::deleteProxyNotWorking($proxy);
                Log::error("captcha is enabled");
            }
        } elseif (isset($content['error']) && ($content['code'] == 404)) {
            $code = $content['code'];
            Log::error("Code = $code , URL = " . $url);

            return [
                'error' => true,
                'code' => $code
            ];
        }

        Log::error('Fail to get content URL, start use proxy =' . $url);
        Log::debug('try to using proxy ...');

        Cache::forget('proxy');
        $proxy = self::getNewProxy();

        if ($proxy) {
            return self::getContent($url, $proxy);
        }

        Log::error('Cannot restart by proxy, end crawl!');

        return [
            'error' => true,
            'code' => 500
        ];
    }

    public static function getProxyType($proxy)
    {
        $ip = "{$proxy['ip']}:{$proxy['port']}";
        $proxyType = $ip;

        if ($proxy['socks5']) {
            $proxyType = "socks5://$ip";
        }

        if ($proxy['ssl']) {
            $proxyType = "https://$ip";
        }

        if ($proxy['socks4']) {
            $proxyType = "socks4://$ip";
        }

        if ($proxy['http']) {
            $proxyType = "http://$ip";
        }

        Log::debug('proxy type = ', [$proxyType]);
        return $proxyType;
    }

    public static function getData($url, $proxy = false)
    {
        $client = new Client();

        try {
            if (!$proxy) {
                $content = $client->get($url);
                return $content->getBody()->getContents();
            }

            $content = $client->get($url, [
                'proxy' => $proxy,
                'connect_timeout' => self::CONNECT_TIME_OUT,
                'timeout' => self::TIME_OUT_RESPONSE,
                'allow_redirects' => false,
                'headers' => [
                    'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13',
                ]
            ]);
            return $content->getBody()->getContents();
        } catch (Exception $exception) {
            Log::error("(getData) Exception messages  = {$exception->getMessage()}");
            Log::error("(getData) status code = {$exception->getCode()}");

            return [
                'error' => true,
                'code' => $exception->getCode()
            ];
        }
    }

    public static function getNewProxy()
    {
        Log::debug('============= start new proxy ==========');
        $proxy = self::getProxyFromDB();

        if (!$proxy) {
            Log::debug('============= empty proxy in db, start using docker ==========');
            $proxy = self::getNewProxyDocker();

            if ($proxy) {
                return $proxy;
            }

            return false;
        }

        if (self::checkProxyWorking($proxy)) {
            Log::debug("============= new proxy is = {$proxy} ==========");
            return $proxy;
        }

        return self::getNewProxy();
    }

    public static function getNewProxyDocker()
    {
        Log::error("=============== start restart docker ================");
        $dockerContainerId = env('DOCKER_CONTAINER_ID');
        $proxy = env('DOCKER_IPV4');

        if (!$dockerContainerId || !$proxy) {
            Log::error('not found docker container id, please insert it in env');

            return false;
        }

        Log::debug("DOCKER_CONTAINER_ID = $dockerContainerId");
        Log::debug("DOCKER_IPV4 = $proxy");

        $process = new Process(["docker restart $dockerContainerId"]);
        $process->run();

        $process = new Process(["curl -Lx  http://172.17.0.2:8118  http://jsonip.com/"]);
        echo $process->run();
        //shell_exec("docker restart $dockerContainerId");
        sleep(10);
//        $ipProxy = self::getData('http://jsonip.com/', env('DOCKER_IPV4'));
//        Log::debug("ipProxy = $ipProxy");

        return $proxy;
    }

    function getRandomUserAgent()
    {
        $userAgents = array(
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6)    Gecko/20070725 Firefox/2.0.0.6",
            "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)",
            "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)",
            "Opera/9.20 (Windows NT 6.0; U; en)",
            "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.50",
            "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.02 [en]",
            "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; fr; rv:1.7) Gecko/20040624 Firefox/0.9",
            "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/48 (like Gecko) Safari/48",
            "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/48 (like Gecko) Safari/48",
        );
        $random = rand(0, count($userAgents) - 1);

        return $userAgents[$random];
    }


    public static function getProxyFromDB()
    {
        $proxyData = Proxy::where('status', Proxy::WORKING)
            ->inRandomOrder()
            ->first();

        if (!$proxyData) {
            Log::debug("proxy empty in database!");
            return false;
        }

        $proxy = self::getProxyType($proxyData->toArray());
        return $proxy;
    }

    /**
     * check proxy is working with aws
     * @param $proxy
     * @return bool|resource
     */
    public static function checkProxyWorking($proxy)
    {
        try {
            $fixUrlToCheck = "https://www.amazon.co.jp";
            $content = self::getData($fixUrlToCheck, $proxy);
            Log::debug("content type = " . gettype($content));

            if ($content && !empty($content) && is_string($content)) {
                $newContent = str_get_html($content);
                $titleraw = $newContent->find('title', 0);
                $title = $titleraw->innertext;
                Log::debug("title = $title");
                if (trim($title) != 'Amazon CAPTCHA') {
                    self::cleanHtml($newContent);
                    return true;
                }
            }
        } catch (Exception $exception) {
            Log::error("Exception messages (checkProxyWorking) = {$exception->getMessage()}");
            Log::error("Exception code (checkProxyWorking) = {$exception->getCode()}");
        }

        self::deleteProxyNotWorking($proxy);
        return false;
    }

    /**
     * check proxy is alive
     * @param $proxy
     * @return bool
     */
    public static function checkProxyAlive($proxy)
    {
        $proxy_arr = explode(':', $proxy);
        $host = $proxy_arr[0];
        $port = $proxy_arr[1];
        $waitTimeoutInSeconds = 10;
        $check = @fsockopen($host, $port, $errCode, $errStr, $waitTimeoutInSeconds);

        if ($check) {
            return true;
        }

        Log::error("proxy [$proxy] not alive");
        self::deleteProxyNotWorking($host);
        return false;
    }

    public static function deleteProxyNotWorking($proxy)
    {
        if ($proxy) {
            Log::debug('start delete proxy not working = ' . $proxy);
            $proxy = explode(':', $proxy);
            $ip = str_replace('//', '', $proxy[1]);
            Proxy::where('ip', trim($ip))->delete();
        }
    }

    /**
     * run when not have any proxy in DB
     * @return bool|string
     */
    public static function getProxyFromApi($proxy = null)
    {
        Log::debug('start get proxy from api');

        if (Cache::has('API_PROXY')) {
            Log::error('api proxy error, try after one hour');
            return false;
        }

        try {
            $code = config('common.API_PROXY_CODE');
            if (!$code) {
                Log::error('not found API_PROXY_CODE');
                return false;
            }

            $urlApi = "http://incloak.com/api/proxylist.php?type=h&out=js&code={$code}&maxtime=500";

            $client = New Client();
            if (!$proxy) {
                $content = $client->get($urlApi);
                $body = $content->getBody()->getContents();
            } else {
                $content = $client->get($urlApi, ['proxy' => "tcp://$proxy"]);
                $body = $content->getBody()->getContents();
            }

            $body = json_decode($body, true);
            foreach ($body as $data) {
                $proxy = "{$data['ip']}:{$data['port']}";
                if (self::checkProxyWorking($proxy)) {
                    return $proxy;
                }
            }

            return false;
        } catch (Exception $exception) {
            Cache::put('API_PROXY', 1, 60);
            Log::error("cannot get proxy from api server, mess= " . $exception->getMessage());
        }

        return false;
    }

    public static function cleanHtml($html)
    {
        if ($html) {
            $html->clear();
            unset($html);
        }
    }
}

0
thg 2 13, 2020 4:14 SA

Trong phần script deploy ấy bạn, có chỗ post-deploy, bạn có thể thêm script vào đó.

0
thg 2 13, 2020 4:04 SA

Dịch bằng google translate mà k có chọn lọc. 👎

0

Helper AwsClient, sao k show luôn b.

+1
thg 2 13, 2020 3:16 SA

🤡

0
thg 2 13, 2020 3:05 SA

ScreenShot_20200213100044.png

Như này là chưa cài thành công đúng k b?

./configure

ScreenShot_20200213100335.png

ScreenShot_20200213101346.png

0

Về phía người dùng có thể ngăn chặn bằng cách cài các extension như uMatrix hay noScript. Cái uMatrix thì có thể dễ dàng thiết đặt để nó tự chặn script và iframe được chèn từ tên miền bên thứ 3 :v

+3
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí