soul源码分析(4)divide插件如何实现负载均衡与探活

说明

本文代码基于soul 2021.2.4 master分支版本。

准备

请先阅读soul官方用户文档 -> HTTP代理, 并事先使用过divide插件,阅读过divide插件源码,源码分析可以参考我之前写过的文章:soul源码分析(1)http插件的使用与soul插件工作流程分析

目标

本文将包括如下内容:

  • divide插件如何实现负载均衡
  • divide插件如何实现端口探活

divide插件如何实现负载均衡?

看过的divide插件源码的童鞋知道,该插件主要逻辑在DividePlugin中:

public class DividePlugin extends AbstractSoulPlugin {
   
    
    .......
            
	@Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
   
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        assert soulContext != null;
        final DivideRuleHandle ruleHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), DivideRuleHandle.class);
        final List<DivideUpstream> upstreamList = UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(selector.getId());
        if (CollectionUtils.isEmpty(upstreamList)) {
   
            log.error("divide upstream configuration error: {}", rule.toString());
            Object error = SoulResultWrap.error(SoulResultEnum.CANNOT_FIND_URL.getCode(), SoulResultEnum.CANNOT_FIND_URL.getMsg(), null);
            return WebFluxResultUtils.result(exchange, error);
        }
        final String ip = Objects.requireNonNull(exchange.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
语法分析是编译器前端的重要组成部分,它负责将词法分析器生成的词法单元转换为语法结构,并检查语法正确性。本文将介绍语法分析程序的设计与实现。 1. 语法分析器的分类 语法分析器可以分为自上而下的语法分析器和自下而上的语法分析器两种。 自上而下的语法分析器以文法的起始符号为目标,从上往下逐步展开,直到匹配输入串或者发现错误。常用的自上而下语法分析算法有递归下降分析法和预测分析法。 自下而上的语法分析器从输入符号出发,逐步将符号组合成更复杂的结构,直到符合文法的起始符号。常用的自下而上语法分析算法有LR分析法、SLR分析法、LALR分析法等。 2. 语法分析器的设计思路 语法分析器通常采用自上而下的递归下降分析法或者自下而上的LR分析法。以下是一个简单的递归下降分析法的设计思路: Step 1:定义语法规则 首先,需要定义文法规则,通常使用扩展巴科斯范式(EBNF)表示。 Step 2:设计语法分析函数 为每个非终结符设计一个语法分析函数,函数的输入是当前的输入符号,输出是生成的语法树。 Step 3:实现语法分析器 将所有语法分析函数组合成一个语法分析器,从文法的起始符号开始逐步展开,直到匹配输入串或者发现错误。 3. 递归下降分析法的实现 递归下降分析法的实现可以采用以下步骤: Step 1:定义语法规则 假设我们要设计一个简单的表达式语法分析器,它的语法规则如下: ``` expr ::= term { (+|-) term } term ::= factor { (*|/) factor } factor ::= id | number | ( expr ) ``` Step 2:设计语法分析函数 为每个非终结符设计一个语法分析函数,函数的输入是当前的输入符号,输出是生成的语法树。 ```c++ // expr ::= term { (+|-) term } ExprNode* parse_expr() { ExprNode* node = parse_term(); while (current_token.type == TOKEN_PLUS || current_token.type == TOKEN_MINUS) { Token op_token = current_token; eat(current_token.type); ExprNode* right = parse_term(); node = new BinaryOpNode(op_token, node, right); } return node; } // term ::= factor { (*|/) factor } ExprNode* parse_term() { ExprNode* node = parse_factor(); while (current_token.type == TOKEN_MULTIPLY || current_token.type == TOKEN_DIVIDE) { Token op_token = current_token; eat(current_token.type); ExprNode* right = parse_factor(); node = new BinaryOpNode(op_token, node, right); } return node; } // factor ::= id | number | ( expr ) ExprNode* parse_factor() { Token token = current_token; if (token.type == TOKEN_ID) { eat(TOKEN_ID); return new IdNode(token); } else if (token.type == TOKEN_NUMBER) { eat(TOKEN_NUMBER); return new NumberNode(token); } else if (token.type == TOKEN_LPAREN) { eat(TOKEN_LPAREN); ExprNode* node = parse_expr(); eat(TOKEN_RPAREN); return node; } else { error("Syntax error"); } } ``` Step 3:实现语法分析器 将所有语法分析函数组合成一个语法分析器,从文法的起始符号开始逐步展开,直到匹配输入串或者发现错误。 ```c++ // Parsing expression ExprNode* parse() { return parse_expr(); } // Main function int main() { // Lexical analysis std::vector<Token> tokens = lexer("1 + 2 * (3 - 4)"); // Syntax analysis current_token = tokens.begin(); ExprNode* root = parse(); // Print syntax tree root->print(); delete root; return 0; } ``` 4. LR分析法的实现 LR分析法的实现可以采用以下步骤: Step 1:定义语法规则 假设我们要设计一个简单的表达式语法分析器,它的语法规则如下: ``` expr ::= term { (+|-) term } term ::= factor { (*|/) factor } factor ::= id | number | ( expr ) ``` Step 2:生成LR分析表 使用LR分析器生成器,根据语法规则自动生成LR分析表。 Step 3:实现语法分析器 使用LR分析表和状态机,从输入符号出发,逐步将符号组合成更复杂的结构,直到符合文法的起始符号。 ```c++ // Main function int main() { // Lexical analysis std::vector<Token> tokens = lexer("1 + 2 * (3 - 4)"); // Syntax analysis LRParser parser("grammar.lr1"); ExprNode* root = parser.parse(tokens); // Print syntax tree root->print(); delete root; return 0; } ``` 5. 总结 本文介绍了语法分析器的设计与实现,包括递归下降分析法和LR分析法。递归下降分析法简单易懂,但是对于左递归文法和二义性文法无法处理;LR分析法可以处理所有文法,但是需要生成LR分析表和状态机,实现复杂一些。在实际应用中,可以根据具体情况选择适合的语法分析算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值