文心一言市场负责人怒怼科大讯飞
针对科大讯飞因AI小作文股价大跌一事,百度文心一言市场负责人张文全在朋友圈怒怼,称“听闻有友商把自己股价大跌,归咎于有人利用文心一言写了篇命题小作文,也是醉了。先别说小作文这事真假 (目前看来只怕是策划痕迹太重),如果AI作文有这本事,百度员工自己先炒一下自己股价不香吗?中国发展自己的大模型技术挺不容易的把精力放到正事上吧,还请友商解决好自己的问题,别动不动就碰瓷别人,大家的眼睛都雪亮的。”科大讯飞股价24日午后意外大幅下跌,午后开盘下跌8.82%至53.88元/股。对此,科大讯飞回应表示,“股价下跌系某生成式AI写作虚假小作文导致,谣传风险为不实消息。”据悉,有人利用文心一言写做了一篇“科大讯飞出现重大风险的警示文”,该消息流出后引发广泛关注。
查看详情点赞1评论收藏浏览952023-05-26 15:27:54我有一个想法,开一个常用的热门工具版块,欢迎大家推荐和留言!!!
点赞3评论7收藏2浏览2362023-05-25 14:11:31Go 简单实现根据网址爬取整站URL(Go爬虫,生成sitemap.xml)
想要实现一个根据一个网站的域名,然后把整个网站的所有链接都爬取出来,以前都是Python爬取,突发奇想用Go也来弄一个,借鉴网上很多资料。整理了一个可以实现的功能,有兴趣的同学可以试试。package main import ( "flag" "fmt" "regexp" "time" "github.com/PuerkitoBio/goquery" "github.com/douyacun/gositemap" "github.com/gocolly/colly" "github.com/gocolly/colly/extensions" ) var priority float64 = 1 func main() { //命令参数获取 targetUrl := flag.String("url", "", "目标站点地址") path := flag.String("path", "", "目标站点地址") Parallelnum := flag.Int("parallel", 500, "并发数") Delay := flag.Int("delay", 0, "延迟(毫秒)") MaxLinks := flag.Int("maxlink", 50000, "最大链接数") //[必须调用]:从 arguments 中解析注册的 flag,不然参数获取都没值 flag.Parse() //参数验证 if len(*targetUrl) == 0 { panic("请传递目前站点地址") } if len(*path) == 0 { *path = fmt.Sprintf("gositemap/%s/", time.Now().Format("20060102_150405")) } st := gositemap.NewSiteMap() st.SetDefaultHost(*targetUrl) st.SetPretty(true) // 每个sitemap文件不能多于50000个链接,这里可以自己配置每个文件最多,如果超过MaxLinks,会自动生成sitemap_index.xml文件 st.SetMaxLinks(*MaxLinks) //xml文件输出地址 st.SetPublicPath(*path) t := time.Now() number := 1 //初始化 创建收集器 c := colly.NewCollector(func(c *colly.Collector) { extensions.RandomUserAgent(c) // 设置随机头 c.Async = true }, //过滤url,去除外链 colly.URLFilters( //regexp.MustCompile("^(https://www\\.uppdd\\.com/)"), regexp.MustCompile("^("+*targetUrl+"/(.*))"), ), ) //控制下速度 c.Limit(&colly.LimitRule{ //DomainGlob: "*uppdd.*", //过滤规则的作用域,不限制则全部链接皆使用该规则 DomainGlob: "*", Parallelism: *Parallelnum, Delay: time.Duration(*Delay), }) // 响应的格式为HTML,提取页面中的链接 c.OnHTML("a[href]", func(e *colly.HTMLElement) { link := e.Attr("href") href := e.Request.AbsoluteURL(link) // 访问url 内部会检查 是否符合 正则表达式 。如果不符合 终止访问该url c.Visit(href) }) c.OnHTML("body", func(e *colly.HTMLElement) { e.DOM.Each(func(i int, selection *goquery.Selection) { //匹配数据(页面dom结构) href := e.Request.AbsoluteURL(e.Attr("href")) //写入链接 url := gositemap.NewUrl() url.SetLoc(href) url.SetLastmod(time.Now()) url.SetChangefreq(gositemap.Daily) //获取页面权重 url.SetPriority(getPriority(number)) st.AppendUrl(url) number += 1 fmt.Printf("计数:%d,链接:%s \n", number, href) }) }) c.OnError(func(response *colly.Response, err error) { //fmt.Println(err) }) c.Visit(*targetUrl + "/") c.Wait() fmt.Printf("连接收集花费时间:%s,收集链接:%d个", time.Since(t), number) //bt,err := st.ToXml() //if err != nil{ // fmt.Printf("异常:%v", err) // return //} //byte切片转string,好查看是否有错误 //btString := string(bt) //输出 //fmt.Println(btString) //生成文件导出 filePath, err := st.Storage() if err != nil { fmt.Printf("%v", err) return } fmt.Println(filePath) } // 递减乱获取权重|很随意 func getPriority(num int) float64 { if num < 20 { return 1 } newS := float64(num) / priority numQ := int(newS) //fmt.Printf("权重:%d \n",numQ) if num >= numQ { priority -= 0.01 } return priority } 我们随便找个网址来试试!#启动命令,其他参数自己也可以尝试,然后完成会把所有的链接都存入一个sitemap.xml文件中 go run . -url=https://gs.dgg.cn然后这个也可以为SEO的同学,爬取整站链接,当做sitemap.xml文件
查看详情点赞1评论收藏1浏览2292023-05-25 11:33:11比较优雅的个性签名推荐
1、只愿你眉眼如初风华如故2、愿我是阳光,明媚而不忧伤3、我将悲欢和酒饮念你平生一展眉4、我的山水落在你的眉间5、凤凰涅槃金鹏展翅待我重出江湖时6、笑叹浮生若梦追忆年华似水7、愿世间美好都如约而至8、晚风吻尽荷花叶任我醉倒在池边9、你活在人间 等于罪恶滔天10、巴黎铁塔下一颗烂草东京樱花下一朵残花11、更相不敌莫让青许两白头12、不愿放手只想到白头13、路是我选的我愿颠沛流离14、恰好那天风烟俱净阳光正好15、ヮ随风飞舞的发丝ヮ风情万种的霓裳16、给我一杯清酒说笑着说别回头17、懂得珍惜才配拥有 懂我心伴我久18、你的感情像彩虹我伸开手却只能握到风19、但愿来日方长不是匆匆一场20、你的笑能抵过风霜是我见过最美的太阳
查看详情点赞评论收藏浏览1092023-05-25 11:22:29Go 接入RabbitMq实操
基本概念什么是消息队列消息队列是一种应用(进程)间的通信方式。生产者只需把消息发布到MQ,消费者只需重MQ中取出,可靠传递由消息队列中的消息系统来确保。消息队列有什么用消息队列是一种异步协作机制,最根本的用处在于将一些不需要即时生效的操作拆分出来异步执行,从而达到可靠传递、流量削峰等目的。比如如果有一个业务需要发送短信,可以在主流程完成之后发送消息到MQ后,让主流程完结。而由另外的线程拉取MQ的消息,完成发送短信的操作。常用的消息队列常用的MQ大概有ActiveMQ、RabbitMQ、RocketMQ、KafkaActiveMQ,基于Java优点:对Java的JMS支持最好;多线程并发;缺点:历史悠久,版本更新慢。现在慢慢用的少了;RabbitMQ,基于Erlang优点:生态丰富,是现在主流的MQ;支持多种客户端、支持AJAX;缺点:对想深入源码的Java选手不太友好;RocketMQ,基于Java优点:为海量数据打造;主张拉模式;天然集群、HA、负载均衡;缺点:生态较小Kafka,基于Scala优点:分布式高可拓展;高性能;容错强缺点:消息重复;乱序;维护成本高什么是RabbitMQ消息中间件erlang:一种并发函数式语言AMQP:Advanced Message Queuing Protocol,高级消息队列协议。由Exchange、Queue和Bind组成RabbitMQ是一个erlang开发的AMQP实现生产者将消息发送到Exchange上,通过Exchange从而Binding到Queues上。Exchange有三种具体类型:direct:如果消息中的RoutingKey和Binding中的BindingKey一致就转发fanout:消息被分发到所有队列中topic:将RoutingKey和队列的模式进行匹配应用场景异步可以理解为将遇到非必须的业务时,立即响应客户端,不关系业务何时完成比如在用户注册时,有将信息写入数据库和发送注册成功邮件两项业务。数据库写入完成即标志着用户注册成功,此时如果继续处理发送邮件的业务,会给客户端带来不必要的等待时间。引入消息队列后,在队列中写入完成注册的消息后,即可完成整个注册流程。至于邮件,可以等到邮件业务从消息队列中取出消息再发送。把不紧急的业务从主线中剥离出来,主线不必考虑不紧急的业务何时完成的时候,可以考虑使用消息队列实现异步。解耦考虑两个系统间存在消息传递,一个系统的故障会影响到整个业务的正常运转。可以用消息队列来保证消息可靠传递比如一个订单系统和一个库存系统,完成订单之后,需要进行库存调度。考虑到如果库存系统故障,会引起已完成的订单消息的丢失,而做很多异常处理会使业务变得臃肿。这个时候可考虑引入消息队列,使用消息队列保证可靠传输,从而减少业务逻辑。削峰考虑短时间的大量请求,可能会带来内存溢出、大面积连接超时等情况,使得服务器崩溃。引入消息队列后,可以控制请求到业务处理系统的流量,从而防止崩溃现象的出现。比如秒杀场景。大量请求同时涌入,服务器不能分配足够的资源响应,或者带宽不足,导致宕机。可以引入消息队列来限流,MQ通过限制同一时间的出口消息,使得流量在服务器能够承受的范围之内。等待一部分请求处理完成之后,再向业务处理系统导入新的消息。----------------------------------------------------------------------------------------------------------------------------------------昨天我们用docker在虚拟机上装了RabbitMq,今天我们就开始用它来实际操作一下。不说废话了,我们开始搞,我这里用的是Go语言。首先,我们先封装方法:package rabbitmq import ( "fmt" "github.com/streadway/amqp" ) type RabbitMq struct { Conn *amqp.Connection Ch *amqp.Channel QueueName string // 队列名称 ExchangeName string // 交换机名称 ExchangeType string // 交换机类型 RoutingKey string // routingKey } type QueueAndExchange struct { QueueName string // 队列名称 ExchangeName string // 交换机名称 ExchangeType string // 交换机类型 RoutingKey string // routingKey } func (r *RabbitMq) ConnMq() { conn, err := amqp.Dial("amqp://admin:123456@192.168.11.66:5672/my_vhost") if err != nil { fmt.Printf("连接mq出错,错误信息为:%v\n", err) return } r.Conn = conn } func (r *RabbitMq) CloseMq() { err := r.Conn.Close() if err != nil { fmt.Printf("关闭连接出错,错误信息为:%v\n", err) return } } // 开启channel通道 func (r *RabbitMq) OpenChan() { ch, err := r.Conn.Channel() if err != nil { fmt.Printf("开启channel通道出错,错误信息为:%v\n", err) return } r.Ch = ch } // 关闭channnel通道 func (r *RabbitMq) CloseChan() { err := r.Ch.Close() if err != nil { fmt.Printf("关闭channel通道出错,错误信息为:%v\n", err) } } // 生产者 func (r *RabbitMq) PublishMsg(body string) { ch := r.Ch // 创建队列 ch.QueueDeclare(r.QueueName, true, false, false, false, nil) // 创建交换机 ch.ExchangeDeclare(r.ExchangeName, r.ExchangeType, true, false, false, false, nil) // 队列绑定交换机 ch.QueueBind(r.QueueName, r.RoutingKey, r.ExchangeName, false, nil) // 生产任务 ch.Publish(r.ExchangeName, r.RoutingKey, false, false, amqp.Publishing{ ContentType: "text/plain", Body: []byte(body), DeliveryMode: amqp.Persistent, }) } // 创建实例 func NewRabbitMq(qe QueueAndExchange) RabbitMq { return RabbitMq{ QueueName: qe.QueueName, ExchangeName: qe.ExchangeName, ExchangeType: qe.ExchangeType, RoutingKey: qe.RoutingKey, } } 接下来我们就我们创建的生产者发送消息:package main import ( "test_rabbitmq/rabbitmq" "test_rabbitmq/utils" ) func main() { qe := rabbitmq.QueueAndExchange{ QueueName: "test_queue", ExchangeName: "test_exchange", ExchangeType: "direct", RoutingKey: "test_routingKey", } mq := rabbitmq.NewRabbitMq(qe) mq.ConnMq() mq.OpenChan() defer func() { mq.CloseMq() }() defer func() { mq.CloseChan() }() test_map := map[string]interface{}{ "mail": "9527@qq.com", "msg": "今天大太阳", } //这里我们发送100条消息 for i := 0; i < 100; i++ { mq.PublishMsg(utils.MapToStr(test_map)) } } 我们可以看到,发送的消息已经在队列当中了。然后我们开始消费消息:package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" "github.com/streadway/amqp" ) func main() { router := gin.Default() router.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "Hello World") }) router.Run(":8081") } func init() { conn, err := amqp.Dial("amqp://admin:123456@192.168.11.66:5672/my_vhost") fmt.Println(err) defer conn.Close() ch, err_ch := conn.Channel() fmt.Println(err_ch) defer ch.Close() ch.Qos(1, 0, false) deliveries, err := ch.Consume("test_queue", "consumer", false, false, false, false, nil) if err != nil { fmt.Println(err) } //消费成功delivery.Ack(true) for delivery := range deliveries { delivery.Ack(true) body := string(delivery.Body) fmt.Println(body) fmt.Printf("%T\n", body) } } 然后我们可以看到数据已经取出来了,队列的消息也已经消费了。
查看详情点赞5评论收藏2浏览992023-05-24 10:27:24Linux centos系统Docker安装 RabbitMq
首先要去docker仓库查找镜像,我们需要下载能可视化操作界面的rabbitMq,所以下载的是management版本。接下来,先建目录,主要是为了存放数据:#建目录 mkdir /server/rabbitmq/data接下来下载rabbitMq镜像:#拉镜像 docker pull rabbitmq:management #启动命令: docker run -d --name rabbitmq \ -p 5672:5672 -p 15672:15672 \ -v /server/rabbitmq/data:/var/lib/rabbitmq \ -e RABBITMQ_DEFAULT_VHOST=my_vhost \ -e RABBITMQ_DEFAULT_USER=admin \ -e RABBITMQ_DEFAULT_PASS=123456\ -m 300m \ --memory-swap=600m \ rabbitmq:management问题:go连接RabbitMQ "no access to this vhost"错误docker exit -it container_name /bin/sh rabbitmqctl add_vhost admin rabbitmqctl set_permissions -p 用户名 admin "." "." ".*"连接的时候指定对应的vhostamqp.Dial("amqp://username:password@ip:5672/admin”)
查看详情点赞1评论收藏浏览642023-05-23 17:44:17Linux centos系统设置静态IP、动态IP
我们装了虚拟机很多时候都需要设置静态IP,不然我们的程序会经常因为IP改变造成各种各种的麻烦。一般默认的是动态IP#进入目录: cd /etc/sysconfig/network-scripts #查看网卡 ll #打开网卡,我这边是ifcfg-enp0s3 vi ifcfg-enp0s3 #这是默认的动态IP,网卡设置 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=enp0s3 UUID=fdeb4637-a424-4d21-82dd-467bd70e3f35 DEVICE=enp0s3 ONBOOT=yes修改为静态IPTYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=static IPADDR=192.168.11.66 NETMASK=255.255.255.0 GATEWAY=192.168.11.1 DNS1=114.114.114.114 DNS2=61.139.2.69 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=enp0s3 UUID=fdeb4637-a424-4d21-82dd-467bd70e3f35 DEVICE=enp0s3 ONBOOT=yes改完保存后,重启网络systemctl restart network主要是加这一段:BOOTPROTO=static IPADDR=192.168.11.66 NETMASK=255.255.255.0 GATEWAY=192.168.11.1 DNS1=114.114.114.114 DNS2=61.139.2.691、BOOTPROTO设置静态static,默认是dhcp2、NETMASK:子网掩码3、GATEWAY:默认网关4、DNS,默认是8.8.8.8下面怎么查找这些数据我虚拟机用的是网络桥接模式:
查看详情点赞1评论收藏浏览572023-05-23 10:13:04CentOS、Ubuntu、Debian 的区别
第一篇Linux 有非常多的发行版本,从性质上划分,大体分为由商业公司维护的商业版本与由开源社群维护的免费发行版本。商业版本以 Redhat 为代表,开源社群版本则以 debian 为代表。这些版本各有不同的特点,在不同的应用领域发挥著不同的作用,不能一概而论。而绝大多数 VPS 上只提供开源社群维护的发行版本。下面就这些不同的 Linux 发行版进行简单的分析。UbuntuUbuntu 近些年的粉丝越来越多,Ubuntu 有著漂亮的使用者介面,完善的包管理系统,强大的站群软件源支援,丰富的技术社群,Ubuntu 还对大多数硬体有著良好的相容性,包括最新的图形显示卡等等。这一切让 Ubuntu 越来越向大众化方向发展。但别忘了:你所需要的只是一个简约、稳定、易用的站群服务器系统而已!Ubuntu 的图形介面固然漂亮,但这也决定了它最佳的应用领域是桌面操作系统而非站群服务器操作系统。如何你希望在学习 Linux 的过程中有个沉浸式的环境,那么 Ubuntu 的确不错:仅仅安装在自己的电脑中而非站群服务器中。从这一点来讲,Ubuntu 并没有在 VPS 安装的操作系统选择之列,相信你也不会为了那数百 M 的驱动与宝贵的内存买单。CentOS你会发现非常多的商业公司部署在生产环境上的站群服务器都是使用的 CentOS 系统,CentOS 是从 RHEL 原始码编译的社群重新发布版。CentOS 简约,命令列下的人性化做得比较好,稳定,有著强大的英文文件与开发社群的支援。与 Redhat 有著相同的渊源。虽然不单独提供商业支援,但往往可以从 Redhat 中找到一丝线索。相对 debian 来说,CentOS 略显体积大一点。是一个非常成熟的 Linux 发行版。Debian一般来说 Debian 作为适合于站群服务器的操作系统,它比 Ubuntu 要稳定得多。可以说稳定得无与伦比了。debian 整个系统,只要应用层面不出现逻辑缺陷,基本上固若金汤,是个常年不需要重启的系统(当然,这是夸张了点,但并没有夸大其稳定性)。debian 整个系统基础核心非常小,不仅稳定,而且占用硬碟空间小,占用内存小。128M 的 VPS 即可以流畅执行 Debian,而 CentOS 则会略显吃力。但是由于 Debian 的发展路线,使它的帮助文件相对于 CentOS 略少,技术资料也少一些。由于其优秀的表现与稳定性,Debian 非常受 VPS 使用者的欢迎。此外还有 Arch Linxu、Gentoo、Slackware 等一系列的 Linux 和 FreeBSD、Unix 等系统,由于其涉及领域更加专业,很少在 VPS 中出现,因此不作介绍。对于初学者,我们建议采用 CentOS 或 Debian,这两种系统都能在配置较低的 VPS 上流畅执行。但是如果 VPS 配置太低(OPENVZ 内存在 128M 以下,或者 XEN 架构内存在 192M 以下),建议采用 Debian;否则建议采用 CentOS,以获取更多的线上帮助与支援,让自己入门更轻松。第二篇CentOS、Ubuntu、Debian 三个 linux 都是非常优秀的系统,开源的系统,也分付费的商业版和 free 免费版本,下面简单比较这三种系统。CentOS 系统很多网站 WP 站长一般都选择 centOS 系统,CentOS 是从 redhat 原始码编译重新发布版。CentOS 去除很多与站群服务器功能无关的应用,系统简单但非常稳定,命令列操作可以方便管理系统和应用,并且有帮助文件和社群的支援。Ubuntu 系统Ubuntu 有亮丽的使用者介面,完善的包管理系统,强大的站群软件源支援,丰富的技术社群,并且 Ubuntu 对计算机硬体的支援好于 centos 和 debian,相容性强,Ubuntu 应用非常多,但对于站群服务器系统来说,个人感觉并不需要太多的各种应用程式,需要的是稳定,操作方便,维护简单的系统。如果你需要在站群服务器端使用图形介面,ubuntu 是一个不错的选择,你需要注意的是,图形介面占用的内存非常大,而内存越大的 vps 价格也越高。Debian 系统Debian 也非常适合做站群服务器操作系统,与 Ubuntu 比较,它没有太多的花哨,稳定压倒一切,对于站群服务器系统来说是一条不变的真理,debian 这个 linux 系统,底层非常稳定,核心和内存的占用都非常小,在小内存的 VPS 就可以流畅执行 Debian,比如 128m 的内存,但 debian 的帮助文件和技术资料比较少。对于小内存,首选 debian,对于非常熟悉 linux 系统的 vps 高手,首选 debian。在系统的选择上,属于新手,首选 CentOS,并不是 centos 比 Debian 和 ubuntu 好,而是 centos 是初学者安装 vps 的首选,它既稳定,占用资源又少,在互联网上能方便搜寻到安装配置的文件,自身的帮助文件也非常强大;如果你是 linux 高手,高手的境界一般都选择 debian,因为高手能在低配的 vps 上稳定执行系统;而 ubuntu,系统虽然免费,但它适合有钱人玩,它占用的资源是比前面两种系统更高,而 vps 基本就是卖内存,内存越高,价格越贵。我们执行著一些全球最大的网际互联网的营运,因此我们对可靠性和稳定性非常重视,是我们的第一要务。为此,我们只使用 Linux 来支撑顾客的系统。但是,我们应该使用哪一个 Linux 的发行版?答案是,CentOS。 为什么呢?作为一个庞大的系统运营商,在很长的一段时间里,我们需要在多种大型系统中找到一个可靠的,可预测的系统,我们需要从世界上最强大的站群软件供应商和开源专案中获得强有力的支援。对于那些最常用的系统,我们需要文件,工具和全球性资源。正因如此,RedHat / CentOS 系列发行版正是我们的选择。他们能够满足以上所有需求,而且问题相对较少、长期稳定,这使得我们能够为成千上万的执行了不同配置、服务和应用的系统提供世界级的维护。RedHat Enterprise Linux (RHEL) 是黄金标准的企业发行版。它每五年左右更新一次,在系统的稳定性,前瞻性和安全性上有著极大的优势。每当新的主版本发行后,比如 5.x 亦或最近的 6.x,所有版本和程式码都将保留不变,只有安全问题或是主要的 bug,例如后门,埠之类的问题,会通过释出新的子版本来修复。CentOS 是 RHEL 发行版对应的开源版本,通常在 RedHat 的释出后就会很快发行。我们使用 CentOS 的原因在于 RHEL 发行版的标准支援服务费用非常高,大约每台站群服务器 800 美元左右,对于我们很多拥有数十台甚至上百台站群服务器的使用者来说,这是必须要控制的成本。RHEL/CentOS 系统有两个潜在的问题:首先,一旦确定了主版本,, 除了安全问题和严重故障会被修复以外,其他内容将不会做任何改变。这虽然对稳定性有好处,但是对许多服务不利。比如 MySQL 和 PHP 服务,它们在这五年的 CentOS/RHEL 主版本释出周期中会进行繁重的开发和大量的修改。例如,MySQL5.0 是当前 RHEL/CentOS 主版本所预设使用的版本,但是当前 MySQL 已经更新到 5.1 和 5.5 版本了。幸运的是,这个问题被 Yum 站群软件包管理器轻易地解决了。如此以来,那些主要的站群软件,例如当前 RHEL/CentOS 中实际的元件,包括核心和所有工具等仍然来自发行版, 但是那些附加的站群软件,例如 Nginx,Apache,PHP,Java 和 MySQL 等等来自更新的站群软件源例如 Fedora; 或者直接从开发商获取更新的版本例如 MySQL。 在我们这里,我们有自己专用的安装镜像站群来全自动的处理所有这些事情。其次,CentOS 的发行会滞后于 RedHat 的发行,包括关键的补丁和修复。这在 RHEL 6.x 的发行周期中尤为显著。但是根据我们的经验,这没什么好担心的,对我们来说永远不会成为问题。很多人询问我们为什么不用基于 Debian 的系统,例如 Debian 或者 Ubuntu 站群服务器。如果在别无选择的情况下,我们的确会支援这个建议,但是根据我们的经验来看,这些系统并不如 RHEL/CentOS 来的稳定和可靠。我们认为,这在某种程度上是由于他们过快的发展和各个版本、组合之间较少的测试且不成熟所导致的。然而尽管他们非常流行,但是主要的服务商和专案都仍然首选 RHEL/CentOS 系统,因为这样他们就可以为企业顾客提供服务,(对 Oracle 和 MySQL 更是如此)。除此之外,基于 Debian 的系统有许多核心和稳定性问题,尤其是在我们的云端计算服务中。对我们而言,唯一使用 Debian/Ubuntu 的原因是:“它们能够为一个系统提供必要的特殊服务时,尤其是当一些驱动程式或者一些 IO 子系统需要一种新的核心的时候”。例如,ext4 档案系统或在最近的核心中日志的改变等;现在,所有这一切都包含在了 RHEL/CentOS6.x 中。当然,多数 Linux 开发者都使用的是 Ubuntu 的桌面版,而且可以理解的是,他们更倾向在开发生产时使用相同的系统,并且还能使用很多有趣的工具。但总体上来说,我们依然认为 RHEL/CentOS 是一个更优越的部署平台,并且已经有十多个客户成功地转向使用 CentOS 作为生产环境并且没有任何问题,但这仍然是艰巨的任务。总的来说,你将更乐于看到一个良好管理的 CentOS 系统。我们有成千上万台站群服务器使用 CentOS 平台,而每年平均只有一台站群服务器崩溃。我们也很难想象它竟如此罕见,所以,挑一个优秀、迅捷、可靠的平台吧!
查看详情点赞评论收藏浏览512023-05-22 15:13:00JS 获取当前IP,城市定位
突然奇想,想做一个获取当前的IP,然后可以做一些客户端的埋点之类的。网上查了很多资料,确实有很多办法可以实现。首先,用百度地图,高德地图的api是肯定可以取得你当前的IP,定位,城市的。我也试了一下可以实现,但是要注册账号之类一堆还是算是麻烦的。然后我也测试了几个记录了下来。1、获取当前IP$.ajax({ url:'https://api.ipify.org?format=jsonp', type:'GET', dataType:'jsonp', success:function(data){ console.log(data); } })这个可以获取到当前的IP,这里是外网IP{ip: '188.25.0.66'}2、获取当前IP,城市因为之前百度可以直接输入IP查找,我也测试了一下。确实也比较方便,暂时也没有太多次数限制。 $.ajax({ url:'https://qifu-api.baidubce.com/ip/local/geo/v1/district', type:'GET', dataType:'application/json', success:function(data){ console.log(data); } })返回结果{ "code": "Success", "data": { "continent": "亚洲", "country": "中国", "zipcode": "610015", "timezone": "UTC+8", "accuracy": "城市", "owner": "中国电信", "isp": "中国电信", "source": "数据挖掘", "areacode": "CN", "prov": "四川省", "city": "成都市", "district": "" }, "charge": false, "msg": "查询成功", "ip": "188.25.0.66", "coordsys": "WGS84" }
查看详情点赞2评论1收藏浏览1122023-05-21 20:39:11Docker-compose 一键部署 Nginx+PHP+MySql+Redis 环境
经过上面docker分别单独部署,nginx,PHP,mysql,redis服务。今天经过半天终于用docker-compose集成了Nginx+PHP+MySql+Redis环境,一键部署,确实方便太多了。好了,回归正题,下面我部署环境的流程。准备工作:安装 Docker(参考之前文章)安装 Docker-compose (参考之前文章)大家可以用我集成好的docker-compose文件,部署分为三步。1、下载文件 docker-compose 部署包下载地址:https://www.aliyundrive.com/s/AwX2ff4ZLyu 提取码: 2f8xGitee仓库地址 :https://gitee.com/lingfeng9527/docker-compose.git2、解压上传到服务器任务一个位置3、执行命令:docker-compose up -d好了,已经部署好了。访问地址就可以看到结果。HTML:PHP文件访问测试MySQL连接:测试Redis:可以看到redis也是没什么问题了。上面已经验证了结果,接下来我们分别说明集成过程,嫌麻烦的朋友或者熟手可以不用看下面的内容!首先准备工作,准备Nginx+PHP+MySql+Redis环境所需要的文件夹和文件:docker-compose 文件:version: '3' #docker-compose语法的版本 services: php: #创建 php的容器 container_name: php74 image: php:7.4.3-fpm ports: - "9000:9000" restart: always privileged: true links: - "mysql" environment: - TZ=Asia/Shanghai build: ./php #直接到 ./php文件下找Dockerfile volumes: - ./www:/www #把容器的/var/www 映射到./www nginx: #创建 nginx容器 container_name: nginx image: nginx:latest ports: #映射 80和443端口到本机 - 80:80 - 8001:8001 - 4433:443 restart: always depends_on: - "php" links: - "php:php74" environment: - TZ=Asia/Shanghai privileged: true volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf #把容器的nginx.conf映射到 ./nginx/nginx.conf - ./nginx/conf.d:/etc/nginx/conf.d #把容器的conf.d映射到 ./nginx/conf.d - ./www:/usr/share/nginx/html #把容器的/usr/share/nginx/html 映射到./www - ./nginx/logs:/var/log/nginx #把容器的/var/log/nginx 映射到./nginx/logs mysql: container_name: mysql image: mysql:latest volumes: - ./mysql/data:/var/lib/mysql #把容器的数据文件夹映射到 ./mysql/data - ./mysql/logs:/var/log/mysql #把容器的日志文件夹映射到 ./mysql/log - ./mysql/conf:/etc/mysql/conf.d #把容器的my.conf文件映射到 ./mysql/my.conf 暂时去掉 ports: - 3306:3306 #把容器的3306端口映射到本机的3306 restart: always privileged: true environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=469ge9g449646he #root密码(我这里乱输的,自己可改) - MYSQL_USER=test #另一个帐号 - MYSQL_PASS=123456 #另一个帐号的密码 redis: #创建 reids的容器 container_name: redis image: redis:latest restart: always ports: - "6379:6379" environment: - TZ=Asia/Shanghai volumes: - ./redis/conf/redis.conf:/etc/redis/redis.conf #把容器的配置文件夹映射到 ./redis/config/redis.conf - ./redis/data:/data command: /bin/sh -c "echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf && redis-server /etc/redis/redis.conf --appendonly yes" # 指定配置文件并开启持久化 privileged: true # 使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限docker-compose 文件就是用来管理各个docker容器服务。www:这个主要是放所有的网站项目,html文件或者PHP文件,如果需要放其他语言的文件,可以参考我的方法集成其他环境。Nginx:Nginx所有相关的配置文件、日志文件MySQL:相关的配置文件,数据文件,日志文件PHP:Dockerfile文件,主要是安装PHP的相关东西,包括PHP扩展。Redis:redis配置和数据文件mkdir /docker-compose/mysql mkdir /docker-compose/mysql/conf touch /docker-compose/mysql/conf/my.conf mkdir /docker-compose/mysql/data mkdir /docker-compose/mysql/logs mkdir /docker-compose/nginx mkdir /docker-compose/nginx/conf.d mkdir /docker-compose/nginx/conf.d/www.test.com.conf mkdir /docker-compose/nginx/conf.d/www.testphp.com.conf mkdir /docker-compose/nginx/logs touch /docker-compose/nginx/nginx.conf mkdir /docker-compose/php touch /docker-compose/php/Dockerfile mkdir /docker-compose/redis mkdir /docker-compose/redis/conf touch /docker-compose/redis/conf/redis.conf mkdir /docker-compose/redis/data mkdir /docker-compose/www touch /docker-compose/www/index.html #可以放入一些html文件 touch /docker-compose/www/php_dome/index.php #可以放入一些php文件 touch docker-compose.ymlmy.conf 文件内容:[mysqld] max_allowed_packet = 20M innodb_buffer_pool_size=128M query_cache_size=56M key_buffer_size = 16M table_open_cache = 64 sort_buffer_size = 512K net_buffer_length = 8K read_buffer_size = 256K read_rnd_buffer_size = 512K myisam_sort_buffer_size = 8M log-bin=/var/lib/mysql/binlog server-id=344 binlog_format=ROWwww.test.com.conf 文件内容:server { listen 80; server_name 192.168.11.146; location / { #注意这里的root目录是容器的网站目录 root /usr/share/nginx/html/; index index.html index.htm index.php; } }www.testphp.com.conf 文件内容:server { listen 8001; server_name 192.168.11.146; location / { root /usr/share/nginx/html/php_demo; index index.html index.htm index.php; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ \.php$ { fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /www/$fastcgi_script_name; include fastcgi_params; } }nginx nginx.conf 文件内容:user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; client_max_body_size 66M; gzip on; include /etc/nginx/conf.d/*.conf; }PHP Dockerfile 文件内容:FROM php:7.4.3-fpm # packages RUN apk --update add \ autoconf \ build-base \ linux-headers \ libaio-dev \ zlib-dev \ curl \ git \ subversion \ freetype-dev \ libjpeg-turbo-dev \ libmcrypt-dev \ libpng-dev \ libtool \ libbz2 \ bzip2 \ bzip2-dev \ libstdc++ \ libxslt-dev \ openldap-dev \ imagemagick-dev \ make \ unzip \ wget && \ docker-php-ext-install bcmath mcrypt zip bz2 pdo_mysql mysqli simplexml opcache sockets mbstring pcntl xsl && \ docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \ pecl install imagick && \ docker-php-ext-enable imagick && \ pecl install swoole && \ docker-php-ext-enable swoole && \ docker-php-ext-install gd && \ docker-php-ext-enable opcache && \ apk del build-base \ linux-headers \ libaio-dev \ && rm -rf /var/cache/apk/* ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /tmp ENV COMPOSER_VERSION 1.5.1 RUN curl -s -f -L -o /tmp/installer.php https://raw.githubusercontent.com/composer/getcomposer.org/da290238de6d63faace0343efbdd5aa9354332c5/web/installer \ && php -r " \ \$signature = '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410'; \ \$hash = hash('SHA384', file_get_contents('/tmp/installer.php')); \ if (!hash_equals(\$signature, \$hash)) { \ unlink('/tmp/installer.php'); \ echo 'Integrity check failed, installer is either corrupt or worse.' . PHP_EOL; \ exit(1); \ }" \ && php /tmp/installer.php --no-ansi --install-dir=/usr/bin --filename=composer --version=${COMPOSER_VERSION} \ && rm /tmp/installer.php \ && composer --ansi --version --no-interaction VOLUME /var/www WORKDIR /var/www CMD php-fpm好了,到这里基本上都介绍完了。
查看详情点赞21评论收藏1浏览7262023-05-19 15:35:40