实现Webhook服务的的猜想!

youfeed

重新编辑放到前面

我用的是workerman v5.0.0-beta.3 PHP8.2

use Fiber;
在控制器开头 
$ch = curl_init();
$fiber = new Fiber(function ($ch) {
    发起HTTP请求
    curl_exec($ch, $still_running);
    // 中断
    Fiber::suspend();
});
// 开始
$fiber->start($ch);

不会了 ......

想要Webman实现Hook订阅服务

很多功能平台服务商都会有这个功能:
1.我平台提供支付回调服务,开发者在平台消费:我将资金变动主动推送到他的服务器去
2.我平台提供汇率通知服务器,开发者设置5m/次 接收最新汇率:我批量推送到开发者服务器去

需要一个并发请求外部http-client

对于【1】点对点完全可以使用webman的redis-queue+http-client组合实现
对于【2】点对多就需要goroutine协程功能,我redis-queue开32个worker消费也会出现不及时情况。

所以需要一个 只管瞬间对N个Url发起访问:返回结果可以弱化。

以下是问的 AI

<?php

// 创建一个协程,用于发送 HTTP 请求
function sendRequest($url)
{
  // 创建一个 `curl` 对象
  $curl = curl_init();

  // 设置 `curl` 对象的选项
  curl_setopt_array($curl, array(
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
  ));

  // 发送请求
  $response = curl_exec($curl);

  // 获取响应码
  $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);

  // 获取响应头
  $headers = curl_getinfo($curl, CURLINFO_HEADER_OUT);

  // 关闭 `curl` 对象
  curl_close($curl);

  // 返回响应码和响应头
  yield $code, $headers;
}

// 创建一个协程池
$pool = new Swoole\Coroutine\Scheduler();

// 启动 10 个协程,用于发送 HTTP 请求
for ($i = 0; $i < 10; $i++) {
  $pool->go(function () use ($url) {
    // 发送 HTTP 请求
    $code, $headers = sendRequest($url);

    // 打印响应码和响应头
    echo "Code: $code\nHeaders: $headers\n";
  });
}

// 等待所有协程完成
$pool->wait();

好的,以下是使用 Golang 实现高效并发 HTTP 客户端服务的示例代码:

package main

import (
    "fmt"
    "net/http"
    "sync"
)

func main() {
    // 创建一个并发池
    pool := sync.Pool{
        New: func() interface{} {
            return http.Client{}
        },
    }

    // 创建一个请求队列
    queue := make(chan *http.Request, 100)

    // 启动 10 个 goroutine 来处理请求
    for i := 0; i < 10; i++ {
        go func() {
            for {
                // 从请求队列中获取一个请求
                req := <-queue

                // 发送请求
                c := pool.Get().(http.Client)
                resp, err := c.Do(req)
                pool.Put(c)

                // 处理响应
                if err != nil {
                    fmt.Println(err)
                } else {
                    fmt.Println(resp.StatusCode)
                }
            }
        }()
    }

    // 将请求放入请求队列
    for i := 1; i <= 100; i++ {
        req, err := http.NewRequest("GET", "http://localhost:8080/", nil)
        if err != nil {
            fmt.Println(err)
        }
        queue <- req
    }

    // 关闭请求队列
    close(queue)

    // 等待所有 goroutine 完成
    <-time.After(time.Second * 10)
}

我想问问 大家在PHP 方面有什么经验嘛。最终我是想把这个任务分发给云函数来处理,不能影响Webman主程序。

508 2 2
2个回答

kspade
  • 暂无评论
MarkGo

对于【2】点对多就需要goroutine协程功能;
應該不需要吧?
量不大的情況下,不是有curl_multi_* 系列並發執行嗎?
量大的情況下,主線程添加去rabbitMQ,各個代理機器去消費就行啦。

  • 暂无评论
🔝