V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  E520  ›  全部回复第 1 页 / 共 4 页
回复总数  69
1  2  3  4  
1:1 价格 也算低嘛~~~
用的什么模型
@morota 这也要看你的消费处理速度,消费的快,那堆积内存就不大, 你可以算一下 1 秒 10 万条数据,占多少内存,去计算就行了
24 天前
回复了 rust 创建的主题 分享创造 一个自动去除图片背景的服务
很慢
24 天前
回复了 rust 创建的主题 分享创造 一个自动去除图片背景的服务
好像不行啊?
25 天前
回复了 caola 创建的主题 Go 编程语言 怎么把全局共享修改为并发的
package main

import (
"context"
"crypto/tls"
"errors"
"fmt"
"github.com/redis/go-redis/v9"
"net"
"net/http"
"net/http/httputil"
"net/url"
"strings"
"sync"
"time"
)

var (
httpAddr = ":80"
httpsAddr = ":443"
redisClient *redis.Client
)

type proxyInfo struct {
mu sync.RWMutex
targetUrl string
requestPath string
requestRawQuery string
requestHeader map[string]string
}

func init() {
redisClient = redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
})
}

func main() {
// 创建 httpTCP
tcpConn, err := net.Listen("tcp", httpAddr)
if err != nil {
panic(err)
}
defer tcpConn.Close()

// 创建 httpsTCP
tcpsConn, err := net.Listen("tcp", httpsAddr)
if err != nil {
panic(err)
}
defer tcpsConn.Close()

pi := &proxyInfo{
requestHeader: make(map[string]string),
}

tlsConn := tls.NewListener(tcpsConn, &tls.Config{
GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
return pi.getCertificate(clientHello)
},
})

httpServer := &http.Server{
Handler: pi.proxyRequestHandler(),
}

go func() {
if err := httpServer.Serve(tcpConn); err != nil {
fmt.Println("HTTP server error:", err)
}
}()

go func() {
if err := httpServer.Serve(tlsConn); err != nil {
fmt.Println("HTTPS server error:", err)
}
}()

select {}
}

// 反向代理
func (pi *proxyInfo) newProxy() (*httputil.ReverseProxy, error) {
pi.mu.RLock()
defer pi.mu.RUnlock()

targetUrl, err := url.Parse(pi.targetUrl)
if err != nil {
return nil, err
}

targetUrl.Path = pi.requestPath
targetUrl.RawQuery = pi.requestRawQuery

fmt.Println("反代的地址:", targetUrl.String())
proxy := httputil.NewSingleHostReverseProxy(targetUrl)

// 连接配置
proxy.Transport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 60 * time.Second,
KeepAlive: 60 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConnsPerHost: 20,
}

originalDirector := proxy.Director
proxy.Director = func(req *http.Request) {
originalDirector(req)
req.URL = targetUrl
req.Host = targetUrl.Host
for k, v := range pi.requestHeader {
req.Header.Set(k, v)
}
}

proxy.ModifyResponse = pi.modifyResponse()
proxy.ErrorHandler = pi.errorHandler()
return proxy, nil
}

// 根据客户端 ClientHello 查询 redis 里域名信息
func (pi *proxyInfo) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
hostName := clientHello.ServerName

// 判断不符合域名长度的 SSL 请求
if len(hostName) < 4 {
return nil, errors.New(hostName + ",域名长度不符合")
}

// 查询 redis 里的域名 SSL 证书
hostConf, err := pi.getHostConf(hostName)
if err != nil {
return nil, err
}

certPublic := []byte(hostConf["certPublic"])
certPrivate := []byte(hostConf["certPrivate"])

certAndKey, err := tls.X509KeyPair(certPublic, certPrivate)
if err != nil {
return nil, err
}

return &certAndKey, nil
}

// 处理代理请求
func (pi *proxyInfo) proxyRequestHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 不是 https 的请求
if r.TLS == nil {
_, err := pi.getHostConf(getHostName(r.Host))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}

pi.mu.Lock()
defer pi.mu.Unlock()

pi.requestPath = r.URL.Path
pi.requestRawQuery = r.URL.RawQuery

// 清空并设置请求头
pi.requestHeader = make(map[string]string)
pi.requestHeader["Referer"] = pi.targetUrl
pi.requestHeader["User-Agent"] = r.Header.Get("User-Agent")
pi.requestHeader["Accept"] = r.Header.Get("Accept")

// 反代
proxy, err := pi.newProxy()
if err != nil {
http.Error(w, "Failed to create proxy: "+err.Error(), http.StatusInternalServerError)
return
}

proxy.ServeHTTP(w, r)
}
}

// 修改 http 响应数据
func (pi *proxyInfo) modifyResponse() func(*http.Response) error {
return func(r *http.Response) error {
typeStr := r.Header.Get("Content-Type")
fmt.Println("响应内容类型:", typeStr)
return nil
}
}

// 错误处理器
func (pi *proxyInfo) errorHandler() func( http.ResponseWriter, *http.Request, error) {
return func(w http.ResponseWriter, req *http.Request, err error) {
fmt.Printf("Got error while modifying response: %v \n", err)
http.Error(w, "server error", http.StatusInternalServerError)
return
}
}

// 获取域名的配置信息
func (pi *proxyInfo) getHostConf(hostName string) (map[string]string, error) {
hostConf, err := redisClient.HGetAll(context.Background(), hostName).Result()
if err != nil {
return nil, err
}

// 检查是否存在目标网址
if targetUrl, ok := hostConf["targetUrl"]; ok {
pi.mu.Lock()
pi.targetUrl = targetUrl
pi.mu.Unlock()
} else {
return nil, errors.New("missing targetUrl in configuration")
}

return hostConf, nil
}

// 获取不含端口的 host
func getHostName(rawUrl string) string {
if !strings.HasPrefix(rawUrl, "http://") && !strings.HasPrefix(rawUrl, "https://") {
rawUrl = "http://" + rawUrl
}
u, err := url.Parse(rawUrl)
if err != nil {
return ""
}
return u.Hostname()
}
可以加入月工资多少,然后每天自动增加工资,这样能更好的看出每日消耗的 和 每日收入的关系,毕竟也就只有工资这么一个收入而已
试用都不给试用。。。!!牛
生成的图片很不像原来的样子
2023-11-20 10:54:21 +08:00
回复了 justin2018 创建的主题 分享发现 微软推出了一个强大且免费的网站分析平台
会不会卡?
来一个
django 还想高性能啊
@jimczj007 火不起来 不开源
这用什么设备 什么软件画的图
这种东西 建议开源!!
2023-09-14 15:08:20 +08:00
回复了 Vogan 创建的主题 分享创造 ReadZen 阅然:焕然一新的稍后阅读和讯息汇聚
交互挺好的
1  2  3  4  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2833 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 29ms · UTC 12:14 · PVG 20:14 · LAX 04:14 · JFK 07:14
Developed with CodeLauncher
♥ Do have faith in what you're doing.