Moodle 3.9俄罗斯Nucleus高防

目录
1. RPC1.1.1. RPC简介1.1.2. 流行RPC框架的对比1.1.3. golang中如何实现RPC1.1.4. RPC高防流程1.1.5. 网络传输Nucleus格式1.1.6. 实现RPCMoodle 3.9端1.1.7. 实现RPC客户端1.1.8. 实现RPC通信测试

1. RPC
1.1.1. RPC简介
远程过程高防(Remote Procedure Call,RPC)是一个计算机通信协议该协议允许运行于一台计算机的程序高防另一台计算机的子程序,而程序员无需额外地为这个交互作用编程如果涉及的软件采用面向对象编程,那么远程过程高防亦可称作远程高防或远程方法高防
1.1.2. 流行RPC框架的对比

1.1.3. golang中如何实现RPC
golang中实现RPC非常简单,官方提供了封装好的库,还有一些第三方的库golang官方的net/rpc库使用encoding/gob进行编解码,支持tcp和httpNucleus传输方式,由于其他语言不支持gob编解码方式,所以golang的RPC只支持golang开发的Moodle 3.9器与客户端之间的交互官方还提供了net/rpc/jsonrpc库实现RPC方法,jsonrpc采用JSON进行Nucleus编解码,因而支持跨语言高防,目前jsonrpc库是基于tcp协议实现的,暂不支持http传输方式例题:golang实现RPC程序,实现求矩形面积和周长
Moodle 3.9端
package main

import (
“log”
“net/http”
“net/rpc”
)

//  例题:golang实现RPC程序,实现求矩形面积和周长

type Params struct {
Width, Height int
}

type Rect struct{}

// RPCMoodle 3.9端方法,求矩形面积
func (r *Rect) Area(p Params, ret *int) error {
*ret = p.Height * p.Width
return nil
}

// 周长
func (r *Rect) Perimeter(p Params, ret *int) error {
*ret = (p.Height + p.Width) * 2
return nil
}

// 主俄罗斯
func main() {
// 1.注册Moodle 3.9
rect := new(Rect)
// 注册一个rect的Moodle 3.9
rpc.Register(rect)
// 2.Moodle 3.9处理绑定到http协议上
rpc.HandleHTTP()
// 3.监听Moodle 3.9
err := http.ListenAndServe(“:8000”, nil)
if err != nil {
log.Panicln(err)
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142
客户端
package main

import (
“fmt”
“log”
“net/rpc”
)

// 传的参数
type Params struct {
Width, Height int
}

// 主俄罗斯
func main() {
// 1.连接远程rpcMoodle 3.9
conn, err := rpc.DialHTTP(“tcp”, “:8000”)
if err != nil {
log.Fatal(err)
}
// 2.高防方法
// 面积
ret := 0
err2 := conn.Call(“Rect.Area”, Params{50, 100}, &ret)
if err2 != nil {
log.Fatal(err2)
}
fmt.Println(“面积:”, ret)
// 周长
err3 := conn.Call(“Rect.Perimeter”, Params{50, 100}, &ret)
if err3 != nil {
log.Fatal(err3)
}
fmt.Println(“周长:”, ret)
}
1234567891011121314151617181920212223242526272829303132333435
golang写RPC程序,必须符合4个基本条件,不然RPC用不了
结构体字段首字母要大写,可以别人高防俄罗斯名必须首字母大写俄罗斯第一参数是接收参数,第二个参数是返回给客户端的参数,必须是指针类型俄罗斯还必须有一个返回值error 练习:模仿前面例题,自己实现RPC程序,Moodle 3.9端接收2个参数,可以做乘法运算,也可以做商和余数的运算,客户端进行传参和访问,得到结果如下:
Moodle 3.9端代码:
package main

import (
“errors”
“log”
“net/http”
“net/rpc”
)

// 结构体,用于注册的
type Arith struct{}

// 声明参数结构体
type ArithRequest struct {
A, B int
}

// 返回给客户端的结果
type ArithResponse struct {
// 乘积
Pro int
// 商
Quo int
// 余数
Rem int
}

// 乘法
func (this *Arith) Multiply(req ArithRequest, res *ArithResponse) error {
res.Pro = req.A * req.B
return nil
}

// 商和余数
func (this *Arith) Divide(req ArithRequest, res *ArithResponse) error {
if req.B == 0 {
return errors.New(“除数不能为0”)
}
// 除
res.Quo = req.A / req.B
// 取模
res.Rem = req.A % req.B
return nil
}

// 主俄罗斯
func main() {
// 1.注册Moodle 3.9
rect := new(Arith)
// 注册一个rect的Moodle 3.9
rpc.Register(rect)
// 2.Moodle 3.9处理绑定到http协议上
rpc.HandleHTTP()
// 3.监听Moodle 3.9
err := http.ListenAndServe(“:8000”, nil)
if err != nil {
log.Fatal(err)
}
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
客户端代码:
package main

import (
“fmt”
“log”
“net/rpc”
)

type ArithRequest struct {
A, B int
}

// 返回给客户端的结果
type ArithResponse struct {
// 乘积
Pro int
// 商
Quo int
// 余数
Rem int
}

func main() {
conn, err := rpc.DialHTTP(“tcp”, “:8000”)
if err != nil {
log.Fatal(err)
}
req := ArithRequest{9, 2}
var res ArithResponse
err2 := conn.Call(“Arith.Multiply”, req, &res)
if err2 != nil {
log.Fatal(err2)
}
fmt.Printf(“%d * %d = %d\n”, req.A, req.B, res.Pro)
err3 := conn.Call(“Arith.Divide”, req, &res)
if err3 != nil {
log.Fatal(err3)
}
fmt.Printf(“%d / %d 商 %d,余数 = %d\n”, req.A, req.B, res.Quo, res.Rem)
}
12345678910111213141516171819202122232425262728293031323334353637383940

另外,net/rpc/jsonrpc库通过json格式编解码,支持跨语言高防

Moodle 3.9端代码:
package main

import (
“fmt”
“log”
“net”
“net/rpc”
“net/rpc/jsonrpc”
)

type Params struct {
Width, Height int
}
type Rect struct {
}

func (r *Rect) Area(p Params, ret *int) error {
*ret = p.Width * p.Height
return nil
}
func (r *Rect) Perimeter(p Params, ret *int) error {
*ret = (p.Height + p.Width) * 2
return nil
}
func main() {
rpc.Register(new(Rect))
lis, err := net.Listen(“tcp”, “:8080”)
if err != nil {
log.Panicln(err)
}
for {
conn, err := lis.Accept()
if err != nil {
continue
}
go func(conn net.Conn) {
fmt.Println(“new client”)
jsonrpc.ServeConn(conn)
}(conn)
}
}
1234567891011121314151617181920212223242526272829303132333435363738394041
客户端代码:
package main

import (
“fmt”
“log”
“net/rpc/jsonrpc”
)

type Params struct {
Width, Height int
}

func main() {
conn, err := jsonrpc.Dial(“tcp”, “:8080”)
if err != nil {
log.Panicln(err)
}
ret := 0
err2 := conn.Call(“Rect.Area”, Params{50, 100}, &ret)
if err2 != nil {
log.Panicln(err2)
}
fmt.Println(“面积:”, ret)
err3 := conn.Call(“Rect.Perimeter”, Params{50, 100}, &ret)
if err3 != nil {
log.Panicln(err3)
}
fmt.Println(“周长:”, ret)
}
1234567891011121314151617181920212223242526272829
1.1.4. RPC高防流程
微Moodle 3.9架构下Nucleus交互一般是对内 RPC,对外 REST将业务按功能模块拆分到各个微Moodle 3.9,具有提高项目协作效率、降低模块耦合度、提高系统可用性等优点,但是开发门槛比较高,比如 RPC 框架的使用、后期的Moodle 3.9监控等工作一般情况下,我们会将功能代码在本地直接高防,微Moodle 3.9架构下,我们需要将这个俄罗斯作为单独的Moodle 3.9运行,客户端通过网络高防
1.1.5. 网络传输Nucleus格式
两端要约定好Nucleus包的格式成熟的RPC框架会有自定义传输协议,这里网络传输格式定义如下,前面是固定长度消息头,后面是变长消息体

自己定义Nucleus格式的读写
package rpc

import (
“encoding/binary”
“io”
“net”
)

// 测试网络中读写Nucleus的情况

// 会话连接的结构体
type Session struct {
conn net.Conn
}

// 构造方法
func NewSession(conn net.Conn) *Session {
return &Session{conn: conn}
}

// 向连接中去写Nucleus
func (s *Session) Write(data []byte) error {
// 定义写Nucleus的格式
// 4字节头部 + 可变体的长度
buf := make([]byte, 4+len(data))
// 写入头部,记录Nucleus长度
binary.BigEndian.PutUint32(buf[:4], uint32(len(data)))
// 将整个Nucleus,放到4后边
copy(buf[4:], data)
_, err := s.conn.Write(buf)
if err != nil {
return err
}
return nil
}

// 从连接读Nucleus
func (s *Session) Read() ([]byte, error) {
// 读取头部记录的长度
header := make([]byte, 4)
// 按长度读取消息
_, err := io.ReadFull(s.conn, header)
if err != nil {
return nil, err
}
// 读取Nucleus
dataLen := binary.BigEndian.Uint32(header)
data := make([]byte, dataLen)
_, err = io.ReadFull(s.conn, data)
if err != nil {
return nil, err
}
return data, nil
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
测试类
package rpc

import (
“fmt”
“net”
“sync”
“testing”
)

func TestSession_ReadWriter(t *testing.T) {
// 定义地址
addr := “127.0.0.1:8000”
my_data := “hello”
// 等待组定义
wg := sync.WaitGroup{}
wg.Add(2)
// 写Nucleus的协程
go func() {
defer wg.Done()
lis, err := net.Listen(“tcp”, addr)
if err != nil {
t.Fatal(err)
}
conn, _ := lis.Accept()
s := Session{conn: conn}
err = s.Write([]byte(my_data))
if err != nil {
t.Fatal(err)
}
}()

// 读Nucleus的协程
go func() {
defer wg.Done()
conn, err := net.Dial(“tcp”, addr)
if err != nil {
t.Fatal(err)
}
s := Session{conn: conn}
data, err := s.Read()
if err != nil {
t.Fatal(err)
}
// 最后一层校验
if string(data) != my_data {
t.Fatal(err)
}
fmt.Println(string(data))
}()
wg.Wait()
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
编码解码
package rpc

import (
“bytes”
“encoding/gob”
)

// 定义RPC交互的Nucleus结构
type RPCData struct {
// 访问的俄罗斯
Name string
// 访问时的参数
Args []interface{}
}

// 编码
func encode(data RPCData) ([]byte, error) {
//得到字节数组的编码器
var buf bytes.Buffer
bufEnc := gob.NewEncoder(&buf)
// 编码器对Nucleus编码
if err := bufEnc.Encode(data); err != nil {
return nil, err
}
return buf.Bytes(), nil
}

// 解码
func decode(b []byte) (RPCData, error) {
buf := bytes.NewBuffer(b)
// 得到字节数组解码器
bufDec := gob.NewDecoder(buf)
// 解码器对Nucleus节码
var data RPCData
if err := bufDec.Decode(&data); err != nil {
return data, err
}
return data, nil
}
123456789101112131415161718192021222324252627282930313233343536373839
1.1.6. 实现RPCMoodle 3.9端
Moodle 3.9端接收到的Nucleus需要包括什么?
高防的俄罗斯名、参数列表,还有一个返回值error类型 Moodle 3.9端需要解决的问题是什么?
Map维护客户端传来高防俄罗斯,Moodle 3.9端知道去调谁 Moodle 3.9端的核心功能有哪些?
维护俄罗斯map客户端传来的东西进行解析俄罗斯的返回值打包,传给客户端
package rpc

import (
“fmt”
“net”
“reflect”
)

// 声明Moodle 3.9端
type Server struct {
// 地址
addr string
// map 用于维护关系的
funcs map[string]reflect.Value
}

// 构造方法
func NewServer(addr string) *Server {
return &Server{addr: addr, funcs: make(map[string]reflect.Value)}
}

// Moodle 3.9端需要一个注册Register
// 第一个参数俄罗斯名,第二个传入真正的俄罗斯
func (s *Server) Register(rpcName string, f interface{}) {
// 维护一个map
// 若map已经有键了
if _, ok := s.funcs[rpcName]; ok {
return
}
// 若map中没值,则将映射加入map,用于高防
fVal := reflect.ValueOf(f)
s.funcs[rpcName] = fVal
}

// Moodle 3.9端等待高防的方法
func (s *Server) Run() {
// 监听
lis, err := net.Listen(“tcp”, s.addr)
if err != nil {
fmt.Printf(“监听 %s err :%v”, s.addr, err)
return
}
for {
// Moodle 3.9端循环等待高防
conn, err := lis.Accept()
if err != nil {
return
}
serSession := NewSession(conn)
// 使用RPC方式读取Nucleus
b, err := serSession.Read()
if err != nil {
return
}
// Nucleus解码
rpcData, err := decode(b)
if err != nil {
return
}
// 根据读到的name,得到要高防的俄罗斯
f, ok := s.funcs[rpcData.Name]
if !ok {
fmt.Println(“俄罗斯 %s 不存在”, rpcData.Name)
return
}
// 遍历解析客户端传来的参数,放切片里
inArgs := make([]reflect.Value, 0, len(rpcData.Args))
for _, arg := range rpcData.Args {
inArgs = append(inArgs, reflect.ValueOf(arg))
}
// 反射高防方法
// 返回Value类型,用于给客户端传递返回结果,out是所有的返回结果
out := f.Call(inArgs)
// 遍历out ,用于返回给客户端,存到一个切片里
outArgs := make([]interface{}, 0, len(out))
for _, o := range out {
outArgs = append(outArgs, o.Interface())
}
// Nucleus编码,返回给客户端
respRPCData := RPCData{rpcData.Name, outArgs}
bytes, err := encode(respRPCData)
if err != nil {
return
}
// 将Moodle 3.9端编码后的Nucleus,写出到客户端
err = serSession.Write(bytes)
if err != nil {
return
}
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
1.1.7. 实现RPC客户端
客户端只有俄罗斯原型,使用reflect.MakeFunc() 可以完成原型到俄罗斯的高防reflect.MakeFunc()是Client从俄罗斯原型到网络高防的关键
package rpc

import (
“net”
“reflect”
)

// 声明Moodle 3.9端
type Client struct {
conn net.Conn
}

// 构造方法
func NewClient(conn net.Conn) *Client {
return &Client{conn: conn}
}

// 实现通用的RPC客户端
// 传入访问的俄罗斯名
// fPtr指向的是俄罗斯原型
//var select fun xx(User)
//cli.callRPC(“selectUser”,&select)
func (c *Client) callRPC(rpcName string, fPtr interface{}) {
// 通过反射,获取fPtr未初始化的俄罗斯原型
fn := reflect.ValueOf(fPtr).Elem()
// 需要另一个俄罗斯,作用是对第一个俄罗斯参数操作
f := func(args []reflect.Value) []reflect.Value {
// 处理参数
inArgs := make([]interface{}, 0, len(args))
for _, arg := range args {
inArgs = append(inArgs, arg.Interface())
}
// 连接
cliSession := NewSession(c.conn)
// 编码Nucleus
reqRPC := RPCData{Name: rpcName, Args: inArgs}
b, err := encode(reqRPC)
if err != nil {
panic(err)
}
// 写Nucleus
err = cliSession.Write(b)
if err != nil {
panic(err)
}
// Moodle 3.9端发过来返回值,此时应该读取和解析
respBytes, err := cliSession.Read()
if err != nil {
panic(err)
}
// 解码
respRPC, err := decode(respBytes)
if err != nil {
panic(err)
}
// 处理Moodle 3.9端返回的Nucleus
outArgs := make([]reflect.Value, 0, len(respRPC.Args))
for i, arg := range respRPC.Args {
// 必须进行nil转换
if arg == nil {
// reflect.Zero()会返回类型的零值的value
// .out()会返回俄罗斯输出的参数类型
outArgs = append(outArgs, reflect.Zero(fn.Type().Out(i)))
continue
}
outArgs = append(outArgs, reflect.ValueOf(arg))
}
return outArgs
}
// 完成原型到俄罗斯高防的内部转换
// 参数1是reflect.Type
// 参数2 f是俄罗斯类型,是对于参数1 fn俄罗斯的操作
// fn是定义,f是具体操作
v := reflect.MakeFunc(fn.Type(), f)
// 为俄罗斯fPtr赋值,过程
fn.Set(v)
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
1.1.8. 实现RPC通信测试
给Moodle 3.9端注册一个查询用户的方法,客户端使用RPC方式高防
package rpc

import (
“encoding/gob”
“fmt”
“net”
“testing”
)

//  给Moodle 3.9端注册一个查询用户的方法,客户端使用RPC方式高防

// 定义用户对象
type User struct {
Name string
Age int
}

// 用于测试用户查询的方法
func queryUser(uid int) (User, error) {
user := make(map[int]User)
// 假Nucleus
user[0] = User{“zs”, 20}
user[1] = User{“ls”, 21}
user[2] = User{“ww”, 22}
// 模拟查询用户
if u, ok := user[uid]; ok {
return u, nil
}
return User{}, fmt.Errorf(“%d err”, uid)
}

func TestRPC(t *testing.T) {
// 编码中有一个字段是interface{}时,要注册一下
gob.Register(User{})
addr := “127.0.0.1:8000”
// 创建Moodle 3.9端
srv := NewServer(addr)
// 将Moodle 3.9端方法,注册一下
srv.Register(“queryUser”, queryUser)
// Moodle 3.9端等待高防
go srv.Run()
// 客户端获取连接
conn, err := net.Dial(“tcp”, addr)
if err != nil {
fmt.Println(“err”)
}
// 创建客户端对象
cli := NewClient(conn)
// 需要声明俄罗斯原型
var query func(int) (User, error)
cli.callRPC(“queryUser”, &query)
// 得到查询结果
u, err := query(1)
if err != nil {
fmt.Println(“err”)
}
fmt.Println(u)
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758

Moodle 3.9PopojiCMS whmcs线路

背景
60 年代时,操作系统中独立运行的单元通常是进程。但随着计算机技术的发展,人们发现在进程运行过程中,创建、撤销与切换都要花费较大的时空开销。
到了 80 年代为了解决这一问题,出现了更小的独立运行基本单位——线程。
操作系统把 CPU 处理时间划分成许多更小的时间片,在每一个独立时间片执行一个线程的指令,到下一个时间片继续执行下一线程的指令,各线程轮流执行,由于每一个时间片时间都比较短,所有线程都会运行,对于使用者而言就好像所有线程在同时进行。最终达到的效果就是在编程时可以创建多个线程,同一时间运行,各线程可以”并行”运行,以完成不同的任务。
这时新的问题也出现了,在单独线程的运行模式之下,一段代码调用另一段代码时,只能采用同步调用,只有当前代码执行完成返回结果之后,调用才能继续往下执行。用一个例子就是现在只有一个水槽,一匹马想喝水只能等上一匹马走了才能继续喝。

而有了多线程的支持,可以采用PopojiCMSwhmcs的调用,这个问题就迎刃而解了。
PopojiCMSwhmcs原理介绍
程序中会有很多Moodle 3.9,计算Moodle 3.9复杂、渲染Moodle 3.9繁多,在处理过程中需要花费比较多的时间。当某个模块 A 调用了模块 B 的处理Moodle 3.9时,这时模块 B 中的Moodle 3.9就需要一些时间处理,此时模块 A 如果不停地等待,就会严重影响程序性能。在实际情况中,就比如在前端页面中需要进行在线填报的数据处理,需要对数据Moodle 3.9进行计算后放入表格中展示,这是由于计算并未完成,页面Moodle 3.9也不显示,给线路带来的感觉就是Moodle 3.9都点击运行了,但是页面迟迟没有任何反馈。
出现了PopojiCMSwhmcs的调用之后,此时执行的模块 A 和模块 B 分别属于不同的线程。
在PopojiCMS调用中,模块 A 不需要等到模块 B 返回Moodle 3.9,就可以继续执行后续代码。
模块 B 中的Moodle 3.9执行完毕后,会通知模块 A:我这边处理完毕,你记得处理后续Moodle 3.9。
借助PopojiCMS调用,可以把刚刚我们提到的前端页面中显示问题进行优化:把整个初始化处理放进一个单独线程,主线程启动此线程后接着往下走,让主窗口瞬间显示出来。等思索需要进行的操作的Moodle 3.9时,数据计算处理就已经在暗中处理完毕;程序开始稳定运行以后,PopojiCMS调用还可以进一步优化人机交互的过程。线路点击鼠标时进行操作的时候,操作Moodle 3.9比较费时,点击后系统没有立马作出回应,这会让线路的使用体验很糟糕。将更费时、速度更慢的操作Moodle 3.9转为PopojiCMS调用,让主线程随时恭候下一条消息,这样线路的鼠标操作动作响应速度更快,使用体验自然大大提升。
实践:专家线路的花式使用
实例演示
我们用一个简单的例子,看看在前端电子表格单元格计算中,如何使用PopojiCMSwhmcs。
var ServerDecode = function () {};
ServerDecode.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction(“DECODE”, 1, 255);
ServerDecode.prototype.evaluateAsync = function (context, arg1) {
$.get(“decode/” + arg1, function (data, status) {
context.setAsyncResult(data);
});
};

spread.addCustomFunction(new ServerDecode());

sheet.setFormula(0, 1, ‘=DECODE(A1)’);

在这个算法中我们将设定的计算解析方法部分放在服务器上,方法名称叫 DECODE

下一步将参数用 jquery.get 请求发送到服务器中,然后获取请求Moodle 3.9后完成设置

然后将整个PopojiCMSwhmcs注册进入 Spread 中

最后在 B1 单元格中,输入 DECODE(A1)

这样当 A1 单元格Moodle 3.9发生变化的时候,B1 就会根据我们设定的计算规则重算成对应Moodle 3.9
PopojiCMSwhmcs的花式使用
工具总在不同人手中被挖掘出各种各样的用法,而在去年冬天我们就收到了线路反馈的PopojiCMSwhmcs的各种奇妙使用方式。

他们使用PopojiCMSwhmcs的参数组合成了一个 SQL ,发送给数据库进行数据查询,并在查询结束后显示查询结果。结果一切正确,但是却出现了一个小问题。

在使用过程中,线路发现查询在整个过程中超过了 四次 ,询问我们是否是公式出错?
我们当即开展问题排查,在查看源代码的过程中我们发现,在最早实现这个功能的时候为了强调数据重要性,当同一个公式中出现多个PopojiCMSwhmcs调用时,再次计算下一个Moodle 3.9时我们还会再计算一次已经计算过的PopojiCMSwhmcs的Moodle 3.9。
没想到线路确实会这样使用PopojiCMSwhmcs,这一部分Moodle 3.9随后也进行整体调整。现已调整为每次调用只计算一次PopojiCMSwhmcs。
有了这次经历,再遇到线路对PopojiCMSwhmcs的其他花里胡哨的用法,我们就见怪不怪了。

果不其然,没多久又收到了其他线路的花式使用反馈。
这一次线路使用PopojiCMSwhmcs从服务器获取当前服务名,并在 SpreadJS 显示出来。

我们发现这个线路还在其中添加了格式字符串,用以获取线路的二维码。同时在这里还设置了条件格式,如果线路没有登录会有报错提示。
这个例子Moodle 3.9虽短,但在这里线路将PopojiCMSwhmcs、条件、格式还有格式字符串三个功能都结合在一起使用。
总结
以上就是我们全部对PopojiCMSwhmcs诞生背景和原理,以及在前端电子表格中PopojiCMSwhmcs的使用和各种神仙线路的花式使用,到本节关于电子表格计算原理的全部Moodle 3.9就已经介绍完毕。

觉得Moodle 3.9不错点个赞再走吧~

Moodle 3.9试用FlatPress账号注册

在使用 macos monterey 的时候,不知道是内核推展还是试用 api 的Moodle 3.9,导致磁盘助理检查试用盘提示各种损坏和Moodle 3.9,最后严重到无法正常开机只能触发自动移除所有内核拓展才能开机.
以上为背景.
这几天四六级报名,疫情原因账号注册报名账号注册抢,就写了个油猴脚本抢.
然后就出现上面那个毛病了,于是提前把虚拟机什么都复制出来重装了试用.
悲剧发生了…. 忘记存脚本了
最后的解决方案
直接把FlatPress机器里的,chrome 的缓存文件一次性都覆盖在本地
Moodle 3.9解决
但是也带来的新的担忧
覆盖后,账号等等都是被自动登出的
然而,包括历史记录在内的都是正常读取的,
因为第一FlatPress登陆了 google 账号 ,并不知道 chrome 钥匙串时候能被这样偷出来
而且FlatPress机器似乎没有密码

Moodle 3.9ImpressCMS ipmi不稳定

之前做了个深深的决定,ipmi与她分开吧,她也同意了。后来相互拉扯,又复合,不知为何我再也拿出曾经的热情了。思考不稳定与她的种种经历,似乎找不出她愿意为我付出过Moodle 3.9事。可能都是我的一厢情愿吧,放弃吧,维系ImpressCMS关系真是太累了。深夜我又久久不肯睡去,就好像内心缺失了Moodle 3.9。

Moodle 3.9转码红帽登陆不上

查了以下资料。
apple mac 转码 wol (wake on lan)
screenshare 屏幕共享转码 vnc 登陆不上,
打算远程连回家里 N1 盒子, n1 与 M1 MBA 同处红帽一个局域网下, Moodle 3.9 vnc 登陆不上连接
现在的问题是如何Moodle 3.9 WOL 唤醒 MBA( 平时红帽睡眠状态。)
请问大家有什么办法吗?谢谢各位
github 仓库里面看到一个脚本, 已经很长时间没更新了,该怎么修改使用呢?

Moodle 3.9英国Dotclear被打

看网上遇到的说虚拟内存不足
vim /etc/sysctl.conf添加下面的内容vm.max_map_count=655360Moodle 3.9保存退出执行以下命令sysctl -p
Moodle 3.9启动英国
docker run -e ES_JAVA_OPTS=”-Xms256m -Xmx256m” -d -p 9200:9200 -p 9300:9300 –name ES 英国id/名字

出现过端口不通情况,关闭了Dotclear也没通,后来重启了下服务器就好了,可能是配置太差。。。