JAVA中的番石榴RateLimiter

问题描述

我想以 5/秒的速率向外部 API 发送请求,如下所示:

export default function CreateOrgan(props)  {
    /* Server State Handling */
    const [serverState,setServerState] = useState();
    const handleServerResponse = (ok,msg) => {
        setServerState({ok,msg});
    };
    const handleOnSubmit = (values,actions) => {
        axios({
            method: "POST",url: "/organs",data: values
        })
            .then(response => {
                props.history.push("/listorgan");
                actions.setSubmitting(false);
                actions.resetForm();
                alert("Organ enregister avec succer");
            })
            .catch(error => {
                actions.setSubmitting(false);
                handleServerResponse(false,error.response.data.error);
            });
    };
    return (
        
                                    <PageWrapper>
                        <Formik
                            initialValues={{ id: "",nom: ""}}
                            onSubmit={handleOnSubmit}
                            validationSchema={formSchema}
                        >
                            {({ isSubmitting,values,errors,touched,isValidating,isValid
                            }) => (
                                <Form id="fs-frm" novalidate>
                                <Row>
                                <Col>
                                    <Label htmlFor="code">
                                        Code
                                        <Input
                                            type="text"
                                            name="id"
                                            autoCorrect="off"
                                            autoComplete="name"
                                            placeholder="Code"
                                            valid={touched.id && !errors.id}
                                            error={touched.id && errors.id}
                                        />
                                    </Label>
                                    {errors.id && touched.id && (
                                        <StyledInlineErrorMessage>
                                            {errors.id}
                                        </StyledInlineErrorMessage>
                                    )}
                                </Col>
                                    <Col>
                                        <Label htmlFor="code">
                                            Nom
                                            <Input
                                                type="text"
                                                name="nom"
                                                autoCorrect="off"
                                                autoComplete="name"
                                                placeholder="Nom"
                                                valid={touched.nom && !errors.nom}
                                                error={touched.nom && errors.nom}
                                            />
                                        </Label>
                                        {errors.nom && touched.nom && (
                                            <StyledInlineErrorMessage>
                                                {errors.nom}
                                            </StyledInlineErrorMessage>
                                        )}
                                </Col>
                                </Row>
                                    <Card.Footer style={{ "textAlign": "right" }}>
                                    <button type="submit" className="btn btn-primary" disabled={isSubmitting} style={{ "width": "120px","margin": "1px","padding": "2px" }}>
                                        Submit
                                    </button>
                                    </Card.Footer>
                                    {serverState && (
                                        <p className={!serverState.ok ? "errorMsg" : ""}>
                                            {serverState.msg}
                                        </p>
                                    )}
                                </Form>
                            )}
                        </Formik>
                                        </PageWrapper>
    );
};

然后我将这个 rateLimiter 传递给方法(通过 for 调用):

//limit sending rate to 5 per second
      RateLimiter rateLimiter = RateLimiter.create(5);

在这方法里面我做了很多事情:

for(...){
    broadcastToken = sendTemplateService.sendbroadcastPetition(broadcastInput,rateLimiter);
}

我的方法正确吗?我不希望整个方法每秒执行 5 次,我想要的是对 API 的调用最多为每秒 5 次。

这个 RateLimiter.create(5) 只会影响下一行?

解决方法

受到速率限制的是从 RateLimiter 对象获取许可。您已经创建了一个 RateLimiter,每秒最多授予 5 个许可。因此,假设您只有一个 RateLimiter,那么您每秒只能执行 rateLimiter.acquire() 5 次,因此您只能运行下一行调用 { {1}}也是每秒 5 次。

restTemplate.exchange 传递给函数使用它似乎有点奇怪,不过。哪个类负责确保 RateLimiter 每秒只被调用 5 次?如果它是 restTemplate.exchange 的类(无论它是什么),那么该类应该创建 sendBroadcastPetition(或接受一个作为构造函数参数)并始终使用那个。现在的情况是,RateLimiter 的调用者可以通过每次传入不同的 sendBroadcastPetition 来突破速率限制。如果是调用者负责执行速率限制,则可以在调用 RateLimiter 之前调用 acquire,并且不要传入 sendBroadcastPetition